Auto resize window content in WPF - c#

When debugging my WPF programs I have noticed that when the window is the set size, the contols look just fine. But when the window is maximized, the content is positioned at the same place as if window has not resized. I want it so that the content and window resize proportionately. How can I do this? Sorry if it is a noobish question, but I'm kinda new in the WPF era.
The XAML code is not completely ready yet but here is some of elements:
<DockPanel>
<StackPanel DockPanel.Dock="Left">
...
</StackPanel>
<TabControl DockPanel.Dock="Right">
...
</TabControl>
<ListView>
...
</ListView>
</DockPanel>

Usually, this is because dimension values are set statically, rather than dynamically. Here's the static approach:
<RowDefinition x:Name="NavigatorRow" Height="120"/>
<RowDefinition x:Name="TaskPanelRow" Height="80"/>
Both rows will have fixed heights, and they won't resize with the window.
Here is the dynamic approach:
<RowDefinition x:Name="NavigatorRow" Height="1*"/>
<RowDefinition x:Name="TaskPanelRow" Height="80"/>
The bottom row still has a fixed height of 80, but the top row will expand to fill whatever space is available. In other words, the rows will resize with the window. Columns work the same way.
If I had three rows, I could do this:
<RowDefinition x:Name="NavigatorRow" Height="1*"/>
<RowDefinition x:Name="CalendarRow" Height="2*"/>
<RowDefinition x:Name="TaskPanelRow" Height="80"/>
The Navigator Row and the Calendar Row will share the available space, with the Calendar Row taking twice the height of the Navigator Row. You get the idea.
So, it's not the container you use, but how you size that container. The one exception, as noted above, is the StackPanel, which does not scale. Use a Grid instead, since it does scale.

Usually this is because the content is hosted in a container which has an explicitly set width and height - like Grid for example.
Post your Xaml or that answer is the best you will get!

Avoid using StackPanels they don't resize dynamically properly.
Ideally you should use a grid and specify percentages if you want things to resize proportionately.

Not sure why everyone is saying stackpanels don't resize dynamically. They handle resizing just like grids do. Just make sure you set your HorizontalAlignment="Stretch" (and/or VerticalAlignment) and the content will expand to fill the stackpanel size. I'm currently using a UI that consists of many nested stackpanels, horizontal and vertical resizing the window expands/contracts all the controls equally inside the window.

Well, you have to have some sort of container for your controls, right? If you're using Canvas and just position your controls absolutely inside there you're pretty much out of luck; this isn't very well for scaling interfaces.
However, there are various container controls that will layout whatever you put in them in certain ways. And if used properly, they scale with a resizing window, too. The Grid is pretty flexible, but StackPanel and DockPanel are very handy at times, too.
You can nest them, if you need.

Use WPF grid with the Widht and Height properties setupped with the "Number*" notion.
For example Width="0.6*", wich is not absolute height but proportional relation to the container. Generaly , if you want resizable content, avoid the fixed size properties as much as you can.
<Grid.RowDefinitions>
<RowDefinition Height="10*"></RowDefinition>
<RowDefinition Height="*" ></RowDefinition>
</Grid.RowDefinitions>
Good Luck.

Related

How to get List-views to automatically adjust height when the window is re-sized in WPF

I'm having trouble getting the two ListViews to adjust their height to the containing window. I am using a GridSplitter between them. I want one ListView to shrink and one to grow when i drag the GridSplitter.
Here is the stripped down xaml code.
<Grid x:Name="Gridthing">
<Grid.RowDefinitions>
<RowDefinition Height="150"/>
<RowDefinition Height="10"/>
<RowDefinition Height="150"/> <!--bottom-->
</Grid.RowDefinitions>
<ListView Name="Things1" Grid.Row="0"/>
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="LightGray"></GridSplitter>
<ListView Name="Things2" Grid.Row="2"/>
</Grid>
However in this example the bottom ListView always 150 tall regardless of what size the window is set too.
Now I can already hear a thousand voices screaming use "*" or "auto" for the the height of the bottom grid row.
However that has a worse problem. The bottom ListView now extends passed the window and has no scroll bar, rendering anything not in the window invisible.
I am looking for a way that allows the two ListViews to take up all the space in the window with a GridSplitter in between and always displays the scroll bar.
Thanks for any help.
The Problem was that my grid was in a userconrol inside a stackpannel inside the main window. I had to swap out the stackpannel for a grid in the main window and then it performed perfectly. thanks dkozl.

StrechToFit in XAML

I want to arrange two UIControls vertically. The top one is variable height while the bottom one is fixed height. How can I make the top element stretch to available height in a StackPanel or Grid?
My question is similar to this question, and the answer suggested the use of DockPanel, however in WP8 there's no DockPanel, so is there any other alternative of that?
A Grid can do that with a row-height of "*" - i.e. a Grid with two rows, the top one "*" the bottom one "auto" would do the trick (not verified for Win8 but should work if memory serves)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
...
</Grid>

TextWrapping, TextTrimming, Center Aligned and vertically stretching

I have a seemingly simple layout problem in Windows Phone. The problem is illustrated in the image below:
My requirements are as follows:
Subtitle must always be visible, at the expense of the overflowing text of the title.
Title and subtitle together must be vertically and horizontally centered.
When I use a StackPanel or auto-height Grid rows, the box will overflow. If I try star height rows
I can't control a large title.
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock ...>Title</TextBlock>
<TextBlock Grid.Row="1" ...>SubTitle</TextBlock>
</Grid>
Found the solution, this will cover everything except the bottom element overflowing the whole screen, in my case this won't be possible. It only works if the parent container does not have infinite height provided (like a StackPanel).
Basically, auto height takes 'precedence' over star-height elements. This gives the bottom TextBlock room to choose its height, and then assigns the remaining available space to the top element.

XY coordinates of WPF button move on runtime?

I got a pretty weird behavior of my WPF application: the XY position of my button on runtime seems to be divergent to that when I set it in my xaml-Editor of Visual Studio (is there a name for it btw?)
It has no alignments set or panels around it, i have only set it by margins. My button has the following code:
<Button Content="OK" Height="23" Margin="213,319,4,7" Name="button3" Width="75" IsCancel="True" Click="button3_Click" IsEnabled="False" />
Edit:
The margins are fixed because it is a non-resizable dialog. As you can see, the button's slightly moved to the left and up:
xaml-Editor:
Runtime:
Why is that and how can I fix it?
I guess the below link about the Alignment, Margins, and Padding Overview will help you to understand how it is works?
Else place a panel wrappers such as Stackpanel, Wrappand or Grid. It's suitable to work the layout of the controls
EDIT : The problem was with the ResizeMode="NoResize". If you remve this attribute in Window tag, then alignment would be good
Link to Refer
Man, that's the worst way to set the position of a UI element in WPF!
Refactor your XAML to something like this:
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Grid.Row="0" Name="TableList" Margin="5"/>
<Button Grid.Row="1" Name="button3" Content="OK"
Margin="5"
Width="75"
HorizontalAlignment="Right"/>
</Grid>
You see? There is a Grid that handles the position of all its children (in this case, a ListView and a Button).
The Button is put on the second Row, aligned to the right (HorizontalAlignment property).
Both the Grid and its children have Margin=5. This guarantees that the margin of every children is equal respect to the adiacent children and to other controls outside the Grid.
Also, the ListView and the Button are perfectly aligned.
The problem with your approach is that you set the Button Width and its Left Margin and its Right Margin. Maybe the total is not correct because the border of the Window eats some pixel, or simply WPF can't handle all the informations together and misses the calculation, who knows, but the consequence is that you must leave at least one parameter free. In my example, I left free the Margins from the Window. The Margin=5 sets only the relative Margin respect to the other controls, but how much the Button is distant from the left border of the Window is something I leave to the WPF graphical engine to calculate.

Grid ColumnDefinition star-width is stretching beyond the parent container's bounds

I've designed a grid row as being another grid with a 20/80 split between two columns, with the one on the left having a min width of 250:
<Grid Grid.Row="1" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" MinWidth="250"/>
<ColumnDefinition Width="4*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="Red" />
<Grid Grid.Column="1" Background="Blue" />
</Grid>
At widths greater than 1250, this works as expected, but as soon as I shrink below that, the first column stops shrinking (as it should) because it has hit 250, but the second column keeps shrinking at the same rate as it did before (rather than collapsing at the same rate of the surrounding window). The result is that a portion of the content is cut out, even though the grid is set to stretch to its container:
Why isn't the blue frame resizing to fit within its parent container the way other star width columns do? Why has setting a min width broken this all of the sudden?
Update: I've rebuilt my entire UI in a sample window (by simply replacing each section's contents with a border), and am unable to reproduce the issue:
It it possible that the contents (which aren't encountering any MinWidth constraints and seem to be resizing properly as well, albeit too slowly like their parent grid columns) are still somehow impacting the grid columns? What about the fact that the original is in a UserControl and this is in a Window?
I apologize - given the information in the original question, it was impossible to answer this question.
Unfortunately for me the problem is a bug in the implementation of the Xceed DataGridControl. By simply replacing each DataGridControl with a border or other control in my original UI, all elements are resized as they should be.
The problem was not that the DataGridControls were encountering their own size constraints. They were in fact continuing to resize themselves as the window resized but they were getting it wrong. My guess is that their implementation relies on walking up the hierarchy or parent UI elements and sizing themselves in accordance to what they calculate their available space to be. I found that nothing short of dictating the exact width of one of the parent elements solves this. If the parent elements use star sizing, and these widths are constrained by column definitions to have a maximum or minimum width or height, the Xceed DataGridControl is oblivious and incorrectly requests a size greater than or less than what is available, even if it's been told to stretch to fit its parent control.
The only workaround I found that doesn't involve boycotting Xceed (which is very tempting) is to redesign the layout so that the first column doesn't grow with the rest of the window and is simply fixed at its minimum width:
<Grid Grid.Row="1" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="4*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="Red" />
<Grid Grid.Column="1" Background="Blue" />
</Grid>
It looks odd and disproportionately squished on large resolution screens, but any attempt to constrain the width while auto-sizing it leads to the behaviour described.
That is totally correct.
In your definition you define that the first columns width has to be at least 250. So 1* has to be at least 250 too. Your second columns width has to be the value of your first column multiplicated by 4. Sorry for my bad english, i hope you can understand.
I cant find an easy and fast solution for that. Maybe you have to bind the MaxWidht property of the second column to the ActualWidth property of the grid and than reduce that value by 250.

Categories