Getting current size of WPF controls - c#

I have Image control in my Window. The size of this Image control is set to "Auto".
<Image x:Name="videoImg" Stretch="Fill" Height="Auto" Width="Auto" />
When i try to get access, it returns 0. How to see real size of this control? It resizes with window.

You can use .ActualHeight and .ActualWidth to get the rendered Height/Width of a control

The thing is, the Width and Height properties let you express the desired size, whereas what you want is the rendered size - which can be accessed (but not set) using the ActualWidth and ActualHeight properties.
It should be noted that these aren't static values either, that is, once set they are not necessarily going to be the same forever after, as it will be re-evaluated upon each rendering sequence...
Because [ActualHeight / ActualWidth] is a calculated value, you should be aware that
there could be multiple or incremental reported changes to it as a
result of various operations by the layout system. The layout system
may be calculating required measure space for child elements,
constraints by the parent element, and so on.
So, depending on your requirements, you might want to consider re-evaluating your data at appropriate points, perhaps when the containing control resizes, for instance.

While some of WPF controls fill up all available space when laid out and rendered, the others don't.
Specifically, the Image control is not of a kind that establishes its size on its own, i.e., in cases when you do not specify control's size explicitly with width/height attributes or the like.
But the Grid control fills up all available space when lacking size-defining attributes. The Page/Window template in Visual Studio has a Grid control as a child of a Page/Window root control, and when the user starts to put controls on a page in a graphical editor, the user-added controls first become children of this Grid control.
If you have used the VS template, and your Image control is a child of the said Grid control, name your Grid with an x:Name attribute, and you can use the Grid's ActualWidth/Height properties for your needs in a code-behind, because the image control grows up to its parent Grid size -- provided you do not specify its size explicitly or otherwise, i.e., setting the Image content.
By the way, the sizing behavior of built-in controls can be changed. You can modify a control and override corresponding dependency properties. See, for example, https://stackoverflow.com/a/6094993 .

Related

How to view inside of a panel control in C# windows form

I am trying to place a panel that I want to have multiple textboxes inside of. I want this panel to fit inside the form and the panel to have a scrollbar. I have autoscroll on and its working as intended, but I want to be able to add controls below the size of the panel. Is there a way I can "full screen" the panel and place items in it or even make the scrollbar a set length instead of just the amount needed to fit the contents. I want to be able to place things underneath what I have there.
Dragging items onto the panel doesn't allow enough room to make things tidy
As an option, you can set the AutoScrollMinSize, in your case, the height of it to a larger value like 1000 temporarily, which sets the virtual (Scrillable) height of the control to 1000. The property determines the minimum size of scrollable area.
As another option, you can AutoScrollMargin, in your case, the height of it, to something like 500 temporarily, which provides an extra 500 pixels space at bottom of the panel. The property determines the minimum margin that should be between the edge of the child control and the edge of the scrollable control.
Then when you are done with the design, just right click on the property and Reset the value of it, to let the control calculate the scroll size.
And I assume you are aware of some obvious workarounds like:
Design the form (including the panel) in a larger size, setting proper dock and and anchor properties for controls, later set the size of form to desired size at run-time, or at design time (after you are done with the initial designs).
Or another workaround, could be just dropping the controls in the panel, and then selecting them and moving them using arrow keys.

what is correct place to initialize width/height of a WPF control

am a beginner and until now I've been re-sizing my control in the VS designer, i wonder what is the correct place to initialize a control property.
Usually you want your user interface controls to automatically resize with the parent Window, for instance when the user resizes the window. In this case, you don't want to specify a hard and fast width/height in your code or in the VS designer. You would instead place the user control inside of one of the appropriate layout controls available in WPF.
There are, however, some times when you want your user control to be one size and always one size. In this case, you would assign it in one of two places:
If it's just a single control, then you would specify the "Height" and "Width" properties in your XAML for that control: <UserControl Width="100" Height="100" />
If it's a size that might be reused in multiple copies of a user control, then you may want to specify the Width and Height properties inside of a common Style.

Horizontal list of user controls (winforms)

I'm certain this can't be as complex as I'm finding it so far!
I'm trying to render a horizontal list of user controls. There will be a large number of them. So some form of Virtual list would be prefereable.
Each user control will contain an image and be selectable.
In Android/Flex/iOS this is trivial with their List Adapters, List Item Renderers etc... However in Win forms it seems very tricky indeed.
I've looked at ObjectListView setting the view mode to Tile. However there doesn't appear to be a way to render horizontally.
I've tried just populating a flow layout with my user controls. But the memory usage goes through the roof as it's loading images.
You could use FlowLayoutPanel container control and set its WrapContents to false and FlowDirection to LeftToRight (which is default). ...and, probably, AutoScroll to true.
EDIT
As to going out of memory, think of simulating virtualization by handling Scroll event and creating/disposing controls as needed.
Derive your own image control from Control and override OnPaint in order to draw the image yourself. Add a property for the path or name of a picture, but don't store the image itself in the control. Google for custom control c#.
Use a cache for the images. A good data structure for this is a circular buffer. This helps in keeping only a limited number of images in memory.

wpf: resizing a control according to its content

I have a control that inherits from Grid, it is a grid of hexagons that are generated dynamically according to the properties.
each of the hexagons is a button and a child of the Grid, and they have a style that displays them as hexagons.
what I want is for the grid to change its size according to the total size of the hexagons.
(I can calculate the exact size needed, but I don't know how to set it).
Basically you've got several options. A simple one is calculating the size yourself and assigning to the Grid's Width and Height.
A more elaborate solution would be to ask yourself a question: which layout is needed for my items? There are some standard containers which do the layout themselves and can grow/shrink with the content. For example, if your objects are just aligned in a line, you can go for StackPanel.

How to get the Width/Height of a collapsed control in WPF?

im wondering if theres an easy way to get the width of a control in WPF at runtime while the control is collapsed.
when i use control.Width ill get the following result: -1.#IND
and control.actualWidth will return 0.0 because its collapsed.
i want to resize my window and then display the collapsed control.
thanks
Edit:
Some details
i have a grid with 2 columns in my window, the 1st column holds a tab control, the 2nd column holds an expander control. i want to extend the width of my window when expanding the expander control, so the content in the 1st column will remain its size.
Put the control in question inside a container (like a ContentControl) and collapse the container rather than the control itself. Then you should be able to simply call Measure (or use the DesiredSize property) on the control to determine how much room it wants.
What size do you expect to get?
The size is not just dependent on the control but also on its container. So the actual size can not be determined unless the control is actually rendered.
Instead of using Collapsed you could make it Invisible that way it will be sized by its own logic and the logic of the container.
EDIT
In the comments it became clear that what the reason was for needing the size of the control:
I have a grid with 2 columns in my
window, the 1st column holds a tab
control, the 2nd column a holds an
expander control. i want to extend the
width of my window when expanding the
expander control, so the content in
the 1st column will remain its size.
My answer:
Set the SizeToContent of the window to WidthAndHeight and set the width of both grid columns to auto. That should take care of it.
I believe you're going about this the wrong way. You can set the Window Width and height to "Auto" and then it will take care of all the resizing stuff.
The problem arises whenever you directly set the Width property of any control(trust me I've done it). Once you do that, you've told WPF hands off of resizing logic, I know what I'm doing.
If you think something isn't resizing at the right time you can add a handler to some event and then call control.InvalidateVisual() or control.InvalidateMeasurement() which will make it go through a whole new layout pass.
You have to call the UpdateLayout method on the control or conainer of control. After that the things may work properly.
In UWP you can determine size of collapsed control by making it visible for a sec and then hiding it again, change is not noticeable:
var oldVisibility = myBorder.Visibility;
myBorder.Visibility = Visibility.Visible;
myBorder.UpdateLayout();
var height = myBorder.RenderSize.Height;
myBorder.Visibility = oldVisibility;
Post which is marked as an answer actually does not answer the question, it just gives a workaround.
To get the size of the collapsed control you need:
Set control's visibility as Hidden (Collapsed won't evaluate).
Call Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)) method of the control.
Get the size from DesiredSize property of the control.
Then you can Collapse your control back.

Categories