Wpf control size to content? - wpf

How do I make a WPF control to change its size according the content in it?

For most controls, you set its height and width to Auto in the XAML, and it will size to fit its content.
In code, you set the width/height to double.NaN. For details, see FrameworkElement.Width, particularly the "remarks" section.

I had a problem like this whereby I had specified the width of my Window, but had the height set to Auto. The child DockPanel had it's VerticalAlignment set to Top and the Window had it's VerticalContentAlignment set to Top, yet the Window would still be much taller than the contents.
Using Snoop, I discovered that the ContentPresenter within the Window (part of the Window, not something I had put there) has it's VerticalAlignment set to Stretch and can't be changed without retemplating the entire Window!
After a lot of frustration, I discovered the SizeToContent property - you can use this to specify whether you want the Window to size vertically, horizontally or both, according to the size of the contents - everything is sizing nicely now, I just can't believe it took me so long to find that property!

I had a user control which sat on page in a free form way, not constrained by another container, and the contents within the user control would not auto size but expand to the full size of what the user control was handed.
To get the user control to simply size to its content, for height only, I placed it into a grid with on row set to auto size such as this:
<Grid Margin="0,60,10,200">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<controls1:HelpPanel x:Name="HelpInfoPanel"
Visibility="Visible"
Width="570"
HorizontalAlignment="Right"
ItemsSource="{Binding HelpItems}"
Background="#FF313131" />
</Grid>

If you are using the grid or alike component:
In XAML, make sure that the elements in the grid have Grid.Row and Grid.Column defined, and ensure tha they don't have margins. If you used designer mode, or Expression Blend, it could have assigned margins relative to the whole grid instead of to particular cells.
As for cell sizing, I add an extra cell that fills up the rest of the space:
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

Related

Windows Phone 8 - Filling a stackpanel with a button

Suppose I make the following screen in my app (this is just an example, actual layout is a bit more complex but works on the same principle):
Vertical StackPanel
TextBlock (fits/wraps its content size AKA Auto size)
Button 1 (Auto)
Button 2
I would like to make Button 2 stretch so that it occupies the remainder of the screen's height, so there cannot be a specific Height property - but VerticalAlignment="Stretch" and VerticalAlignment="Bottom" don't do the trick, and in fact don't do anything at all. Is there any way to handle that?
in this case i generally prefer to use a grid, you can use something like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
Change the StackPanel to a Grid with 3 rows, first two of Auto size and the last *.

Window Resize with Mouse drag?

I have a WPF Application.I want to implement Resize the window(whatever size) using mouse drag with window corners or sides. like notepad or wordpad.Controls are strecthed according to window size.
can any one help on this?
By default, the Window class (<Window> element) comes with style that is 'Resizeable' - that is a thik border which the user can resize by dragging. If you do nothing to the Visual Studio's generated WPF Window item you'll get a resizeable Window: The property that dictates this behavior is ResizeMode. If you want to have a little Grip, then set the followign property: ResizeMode="CanResizeWithGrip"
There are many ways to acheive controls proportional to the embedding element. One common method is to use the element, and define ahd columns width and row heights in terms of '*'. The example below will drow two buttons that are 2/5 of the height each:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="2*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Button Grid.Row="0" />
<Button Grid.Row="1" />
</Grid>

in wpf how do i make a datagrid fit the window height

I have a grid with 3 columns and 2 rows
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
I the lower left cell, i have a data grid, with AutoGenerateColumns=True which can load many rows. What I want to do is for the data grid height to maximize to fit the window, and for the user to be able to use the datagrid scrollbar to scroll the rows up and down.
What happens is that the datagrid flows of the bottom of the window, and even if i set the
ScrollViewer.VerticalScrollBarVisibility="Visible"
of the datagrid, the scrollbar has no effect and the rows flow downwards. Somehow the datagrid does not feel restricted...
What to do?
Try setting your DataGrid's HorizontalAlignment=Stretch and VerticalScrollBarVisibility=Auto
If that doesn't work, you may also need to bind the Grid's Height to the Window Height so that it doesn't auto-grow to fit its contents. Usually I use Height="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=ActualHeight}" (It might be RenderSize.ActualHeight instead of just ActualHeight... I forgot.
Another alternative is to use a DockPanel instead of a Grid since that control doesn't auto-grow to fit its contents. Instead it'll stretch its last child to fill the remaining space.
I had the same problem but binding to the Window height did not completely solve the problem for me. In my case the DataGrid still extended 2 to 3 inches below the Window's viewable area. I believe this was because my DataGrid started about 2 to 3 inches below the top of the Window.
In the end I found that it was not necessary to bind the DataGrid's height at all. All I had to do was change the DataGrid's direct container.
For me, the following XAML setup causes the DataGrid to extend beyond the size of the Window when enough rows are added. Notice that the DataGrid sits within a StackPanel.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="75"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<!-- StackPanel Content accounting for about 2-3 inches of space -->
</StackPanel>
<!-- DataGrid within a StackPanel extends past the vertical space of the Window
and does not display vertical scroll bars. Even if I bind the height to Window
height the DataGrid content still extends 2-3 inches past the viewable Window area-->
<StackPanel Grid.Row="1">
<DataGrid ItemsSource="{StaticResource ImportedTransactionList}"
Margin="10,20,10,10" MinHeight="100">
</DataGrid>
</StackPanel>
</Grid>
However, simply removing the StackPanel fixed the problem for me.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="75"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<!-- StackPanel Content accounting for about 2-3 inches of space -->
</StackPanel>
<!-- Removing the StackPanel fixes the issue-->
<DataGrid Grid.Row="1" ItemsSource="{StaticResource SomeStaticResource}"
Margin="10,20,10,10" MinHeight="100">
</DataGrid>
</Grid>
As the original post is quite old, I should note that I am using VS2017 and .Net Framework 4.6.1 but I am not sure if this has any bearing.
You have to define the column and row where the DataGrid is with *.
You say it is on the lower left cell. The row is ok but your column there has Width="Auto".
The AutoGenerateColumns=True gives a mess if Width="Auto".

WPF - DockPanel Question

I am very new to WPF and am trying to understand the DockPanel control. I am building a Window, and am using a DockPanel in order to dock controls the way I want them. However, is it possible to dock the DockPanel itself, say to the top of the Window? I can't seem to find a way to do this. Ideally I would like to have the DockPanel dock itself to the top of my Window so that when the Window is resized, it grows or shrinks as the window is resized horizontally.
The problem is I cannot find a Doc property on the DockPanel itself. Is this not possible to do?
You would need to place it within another DockPanel if you wished to dock it.
That being said, my experience has been that when a layout gets to the level of complexity you are describing, it's often better to switch to using a Grid control. This gives you a huge amount of control over layout, and makes having dynamically growing rows/columns (with fixed size portions between) easy.
Edit in response to comments:
You can use a Grid that scales as needed. For example, by using star syntax, you can have a grid where the top row is always 1/3rd of the window size, and the bottom row is 2/3rds, like so:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
</Grid>
For details on options for sizing, see GridLength. You can use "Auto" (fit to contents), "*" to scale based on space, or a fixed height (put in a number).
I'm not sure if this what you want but I have a DockPanel with a Menu. When I resize the window the menu resizes with it.
Here is my code:
<Grid>
<DockPanel Height="50" Margin="0" Name="MenuDockPanel" VerticalAlignment="Top" Width="Auto">
<Menu Height="23" Name="MenuPanel" Width="Auto" VerticalAlignment="Top">
<MenuItem Header="_File">
</Menu>
</DockPanel>
<Grid>
Hope this helps

WPF layout with several fixed height parts and certain parts relative to window size

At moment my main layout consists of vertically oriented stack panel and it looks like this:
Root StackPanel
StackPanel - fixed Height 150
(horizontal orientation)
StackPanel - relative Height must be
behalf of free space left on screen
(but at least 150 px). Used by Telerik
GridView Control, if I don't specify Height or MaxHeight Telerik GridView Height becomes very large and does not fit my window.
StackPanel - fixed Height 100
(horizontal orientation)
StackPanel - relative Height must be
half of free space left on screen
(but at least 150 px). Used by Telerik
GridView Control, if I don't specify Height or MaxHeight Telerik GridView Height becomes very large and does not fit my window.
StackPanel - fixed Height 100
(horizontal orientation)
The view must totally fit available screen size.
The problem is that I don't understand how to make certain areas of my view resize depending on available screen size.
Is there is easy way to solve it, or should I be binding to Window height property and doing math?
Thank You very much!
I dont have the telerik controls to hand to test so this is off the top of my head - can you not use a grid as the basis of your control rather than a stackpanel like this? - if this is still a problem then post some code up and we can take a look at what you are trying to achieve.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="150"/>
<RowDefinition Height="*"/>
<RowDefinition Height="100"/>
<RowDefinition Height="*" />
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" />
<StackPanel Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<StackPanel Grid.Row="2" />
<StackPanel Grid.Row="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<StackPanel Grid.Row="4" />
</Grid>

Resources