Saving GridSplitter position - wpf

I have this:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="50*" />
</Grid.ColumnDefinitions>
<GridSplitter Background="{x:Static SystemColors.ControlBrush}"
Grid.Column="1"
Margin="0,0,0,0"
Name="splitter"
HorizontalAlignment="Stretch" />
I'm trying to save and restore the splitter position. I'm using grid.ColumnDefinitions[0].Width, which returns the width of the column in pixels.
When I restore the position, how do I restore AND keep the 50* setting, so that when you resize the window, the column resizes correctly?

The Width property is not a simple double, it is a System.Windows.GridLength object which contains the Value property (double) and a GridUnitType property (GridUnitType) which is an enum.
So, to set your column's width to 50*:
grid.ColumnDefinitions[0].Width = new GridLength(50, GridUnitType.Star)
To save and restore all you need to do is to save the value and the GridUnitType for each column.
Hope it helps.

Related

WPF: Calculating the size of a Grid Column

I have a grid that contains three columns.
<Grid Background="AliceBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="2*" Name="ManualControlsSplit" />
</Grid.ColumnDefinitions>
The first column contains a Grid and a chart.
The second column contains a GridSplitter.
The third column contains a StackPanel which contains a number of TextBlocks, Buttons and Grids containing TextBlocks and Buttons. Text size is dynamic and based on translation resources.
I need to calculate the minimum width that the contents of the third column would ideally like to be able to be drawn into so that the contents are not clipped.
My knowledge of WPF is limited to what I can google so any help would be appreciated.
With layout in WPF, you can allow one if not more of the Grid.Columns to be <ColumnDefinition Width="Auto"/>. This essentially tells WPF to allow as much space as the contained controls want. The use of Auto cascades too, so in StackPanel you refer to, you can make that controls width Auto as well, likewise with the items it contains; if the stack panel merely contains a TextBlock (via some template or whatever), then you can also set this width to Auto and the width with set itself according to the contained text.
<Grid Background="AliceBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
...
<StackPanel Grid.Column=2
Width="Auto">
<TextBlock Width="Auto"
Text="This is TextBlock"/>
...
</StackPanel>
...
</Grid>
In this case the Text of the TextBlock sets the width of the StackPanel, which in turn sets the width of the 3rd grid column.
I hope this helps.
My WPF XAML setup is as follows (bits removed to keep this simple):
<UserControl ....>
<Grid Background="AliceBlue" Name="TopGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="12*" Name="Graph" />
<ColumnDefinition Width="5" Name="GridSplitter" />
<ColumnDefinition Width="2*" Name="ManualControlsSplit" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="AliceBlue"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<!-- A Graph and simple controls -->
</Grid>
<!-- GRID SPLITTER -->
<GridSplitter Grid.Column="1" Width="5"
HorizontalAlignment="Stretch" Name="Splitter" />
<Label Grid.Column="1" Content="⁞" Foreground="White"
Background="DarkGray"
VerticalAlignment="Center" FontSize="26" FontWeight="Bold"
IsHitTestVisible="False"/>
<!-- end GRID SPLITTER -->
<StackPanel Grid.Column="2" Grid.Row="0" Margin="5"
Name="TemperatureControls">
<!-- Load of Controls -->
</StackPanel>
</Grid>
</UserControl>
To calculate the desired width I use the following code:
// get my UserControl object
var manualControlView = userControl as HeatingController.Views.ManualControlView;
// Query the current width of THIRD column
double actualWidth = manualControlView.ManualControlsSplit.ActualWidth;
// Set up a BIG size (this has to be bigger size than the contents of the
// THIRD column would ever need)
Size size = new Size(400, manualControlView.TopGrid.ActualHeight);
// Ask WPF layout to calculate the Desired size.
manualControlView.TemperatureControls.Measure(size);
double width = manualControlView.TemperatureControls.DesiredSize.Width;
if (actualWidth <= width)
{
// Too small - do something
}
else
{
// big enough - do something else.
}
The variable 'width' now contains the value I wanted to calculate.

How to automatically collapse a Grid Column in xaml?

Basically I'm getting some data from a service and displaying the results in a listbox. The template for the items is using a grid. NOTE: If there is a better way let me know.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"/>
<TextBlock Grid.Column="1"/>
</Grid>
The problem is, that sometimes an image is not returned. In that case the column for the image should collapse and the text column should take up the full width.
I've tried a couple of different ways already with no luck. How can I collapse this column when no image is returned?
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"/>
<TextBlock Grid.Column="1"/>
</Grid>
Setting the image column width to auto will resize the column width according to the image size. If there is no image the size will be set to 0. The text column is set to *, this way it always takes all the available space.
Note: If your images are big, you may need to set MaxWidth as well.
You can use Expander control and set IsExpanded property.

WPF: Star in ColumnDefinition not expanding columns

I have a user control that need the 1st and 3rd column to have the same width at all time.
My code is a follows:
<UserControl x:Class="UserControls.ListBoxSelector"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="5*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox x:Name="ListBox_Source" Grid.Column="0" Grid.Row="0" />
<StackPanel Grid.Column="1" Grid.Row="0" Orientation="Vertical">
<Button Content=">" Click="Button_Add_Click"/>
<Button Content="<" Click="Button_Remove_Click" />
</StackPanel>
<ListBox x:Name="ListBox_Destination" Grid.Column="2" Grid.Row="0" />
</Grid>
</UserControl>
The result is not as expected as column 3 (ListBox_Destination) is not expanded at all.
Isn't the 5* in ColumnDefinition enough to force the 2 listbox to the same width??
UPDATED : Sorry that I forgot to mention that the problem only occurs when I put the control inside a RibbonGroup using Microsoft Ribbon for WPF
Sometimes, when you put your control in certian types of layout controls (like a StackPanel), it won't size as expected because the parent layout will only size the child to it's minimum desired size (just enough to show the content). This may be why you are seeing this when you put it in the RibbonGroup. Try giving your Grid a Width or MinWidth and see if that makes a difference.
yes it forces the columns 1 and 3 to be of the same size, but it doesnt gaurentee the content (listboxes) inside the colulms will be of the same size. You have to set the size of content to take up whole space

Silverlight: Set MaxWidth of a textblock to containing column width

in my Silverlight 4 App, I have a simple 3-columns Grid, that contains 3 Textblocks.
<Grid Background="{StaticResource BrushCharacteristicListBoxItemBackground}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="TextBlockCharacteristicName" Text="{Binding Property1}" HorizontalAlignment="Left" TextTrimming="WordEllipsis" ToolTipService.ToolTip="{Binding Text}" Margin="6,0,0,0" />
<TextBlock x:Name="TextBlockSeperator" Text="=" Grid.Column="1" />
<TextBlock x:Name="TextBlockCharacteristicValue" Text="{Binding Property3}" Grid.Column="2" HorizontalAlignment="Right" Margin="0,0,6,0" />
</Grid>
The width of the Grid depends on the containing user control. Now I want to cap the size of the first and the third textblock to the current size of their containing column, probably using MaxSize and bind it somehow to the size of the Column of the Grid.
Can anyone here tell me how to do this?
Thanks in advance,
Frank
By default the HorizontalAlignment property of the TextBlock is set to "Stretch" so it will fill the available size of the column its in, regardless of its content. Is that what you want?
Perhaps for some reason you do not want the TextBlock to be as wide as the Column it is in if its content does not need all the available space?
If so set the TextBlock.HorizontalAlignment to "Left". The TextBlock will then be only as wide as it needs to be until it reaches the width of the column, then its width will be constrained by the column.

How to stretch the image of (1* 66 ) pixel

In a WPF Application using XAML,
I have 2 images, which needs to be oriented horizontally. One is of width 784 * 66 and other is 1 * 66.
while, design time, since my window is auto it shows properly, but during runtime, the window is of 1280 width... so, the image 1 * 66 should stretch and cover the rest (1280 - (784 + 1))
|________________________________|_|
should become
|________________________________|___________________________|
which means , my firstimage should have the same width (784) and the second image should stretch to cover the rest even though its only one pixel.
Please help me
<Grid HorizontalAlignment="Left" Height="66" Name="grdTopImages">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" MinWidth="1" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="66" />
</Grid.RowDefinitions>
<Image Name="imgClientPhoto" Grid.Column="0" Grid.Row="0" Source="/Honeywell.eHTMP;component/Resources/_left.gif"></Image>
<Image Name="imgExtraImg" Grid.Column="1" Grid.Row="0" Stretch="Fill" Source="/Honeywell.eHTMP;component/Resources/_right.gif"></Image>
</Grid>
Thanks
Ramm
You've got your column definitions the wrong way around. Should be:
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
This means the first column is as big as it needs to be, and the second column takes up whatever's left.

Resources