WPF How to make control resize relative to next control - wpf

I have defined the following XAML:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="200" />
<ColumnDefinition MinWidth="200" />
<ColumnDefinition MinWidth="500" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Margin="2,2,5,2">
<GroupBox Header="Computer">
<DockPanel>
<ComboBox MinWidth="100" Name="cmbComputerNames" IsEditable="True" DockPanel.Dock="Left" HorizontalAlignment="Stretch" Width="auto" />
<Button Content="Connect" Name="bConnect" Width="65" HorizontalAlignment="Right" />
</DockPanel>
</GroupBox>
</StackPanel>
<Button Grid.Column="1" Content="Two" Margin="1,2,5,2" />
<Button Grid.Column="2" Content="Three" Margin="1,2,2,2" />
<GridSplitter Height="100" Width="4" Grid.Column="0"/>
<GridSplitter Height="100" Width="4" Grid.Column="1"/>
</Grid>
So, the left grid column is resizable. I want the "Connect" button to remain right-aligned and with same width. The combobox however, should be left-aligned and the width should grow as the column is resized, so the distance to the connect button remains the same.
Doesn't work:
Can anyone tell me how I can achieve that?

Since this is too long for a comment
Replace DockPanel with Grid and try this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<GroupBox Header="Some text here">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ComboBox MinWidth="100"/>
<Button Grid.Column="1" Content="A button" Margin="5"/>
</Grid>
</GroupBox>
<GridSplitter Grid.Column="1" Grid.RowSpan="2" ResizeDirection="Columns" ResizeBehavior="PreviousAndNext" Width="10"/>
<Button Content="some button" Grid.Column="2"/>
</Grid>
#Andy, if you could produce an answer then I will delete mine.

Related

Trying to get element alignment correct in xaml

I am trying to get the first label and text box to align to the left side of the screen, and the second label and text box to align to the right side of the screen. What am I missing here? The second set of controls will not align to the right.
Thanks in advance!
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="0">
<StackPanel Orientation="Horizontal">
<Label Content="Active Profile"></Label>
<TextBox Name="activeProfileName" Width="100" Height="20"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
<Label Content="Create A New Profile"
HorizontalAlignment="Right"></Label>
<TextBox Name="activeProfileNamey"
Width="100" Height="20"
HorizontalAlignment="Right"></TextBox>
</StackPanel>
</StackPanel>
</Grid>
The outter StackPanel is your problem. Use Grid instead. Your question is actually a duplicate of the Aligning controls on both left and right side in a stack panel in WPF
Here is the code with Grid:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal">
<Label Content="Active Profile"></Label>
<TextBox Name="activeProfileName" Width="100" Height="20"></TextBox>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Right" >
<Label Content="Create A New Profile"
HorizontalAlignment="Right"></Label>
<TextBox Name="activeProfileNamey"
Width="100" Height="20"
HorizontalAlignment="Right"></TextBox>
</StackPanel>
</Grid>
</Grid>

WPF - GridSplitter not working between two grids

I have some issues with getting the grid splitter to work properly.
I have placed the GridSplitter between two grids but the problem is that the grid splitter attaches to left grid which is the only one I can move with the splitter. If I move the left grid towards the right grid, the right grid will get smaller but if I move it away from the right grid it will not expand more than its initial size.
How can I place the GridSplitter in such a way that it allows me to adjust the width of the right grid and then reducing the width of the left grid if it is dragged that way.
I did add a SharedSizeGroup to one of the child grids of the right grid but I'm not sure if that is relevant to my problem, removing it didn't solve anything.
I have also tried to play around with the ResizeBehavor of the GridSplitter also without luck.
I hope it makes sense.
XAML:
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="3"></TextBlock>
<Label Grid.Row="0" Grid.Column="0" VerticalContentAlignment="Center" Margin="5"/>
<ComboBox Grid.Row="0" Grid.Column="1" MinWidth="200px"/>
<Label Grid.Column="2" VerticalContentAlignment="Center" Margin="10 5 5 5"/>
<ComboBox Grid.Row="0" Grid.Column="3" IsEditable="True" MinWidth="250px"/>
</Grid>
<!--Below grid only shown when errors are present. Not relevant for problem -->
<Grid Grid.Row="1" Grid.ColumnSpan="2" Grid.RowSpan="2" Grid.Column="0">
<TextBlock/>
</Grid>
<!-- The "Left" Grid -->
<Grid Grid.Row="1" Grid.RowSpan="2" Grid.Column="0">
<WebBrowser></WebBrowser>
</Grid>
<GridSplitter HorizontalAlignment="Stretch" ResizeDirection="Columns" Width="10" Grid.Row="1" Grid.Column="1" ResizeBehavior="PreviousAndNext"/>
<!-- The "Right" Grid -->
<Grid Grid.Row="1" Grid.RowSpan="2" Grid.Column="2" Panel.ZIndex="2" MinWidth="200" HorizontalAlignment="Right">
<Border BorderBrush="Blue" BorderThickness="1" MinWidth="200" Background="#4C808080" >
<GroupBox MinWidth="200">
<GroupBox.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" Margin="5"/>
</Grid>
</DataTemplate>
</GroupBox.HeaderTemplate>
<Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Label" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Margin="5" VerticalAlignment="Center" Grid.ColumnSpan="2"/>
<TextBox Grid.Column="1" Grid.Row="0" Margin="5,7" VerticalAlignment="Center" IsReadOnly="True" />
<Label Grid.Column="0" Grid.Row="1" Margin="5" VerticalAlignment="Center" Grid.ColumnSpan="2"/>
<TextBox Grid.Column="1" Grid.Row="1" Margin="5,7" VerticalAlignment="Center" IsReadOnly="True"/>
<ItemsControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Label" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Margin="5" VerticalAlignment="Center"/>
<TextBox Grid.Column="1" Grid.Row="0" Margin="5" VerticalAlignment="Center" IsReadOnly="True"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</GroupBox>
</Border>
</Grid>
</Grid>
</Grid>
Have a look at this
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="3"></TextBlock>
<Label Grid.Row="0"
Grid.Column="0"
VerticalContentAlignment="Center"
Margin="5" />
<ComboBox Grid.Row="0"
Grid.Column="1"
MinWidth="200px" />
<Label Grid.Column="2"
VerticalContentAlignment="Center"
Margin="10 5 5 5" />
<ComboBox Grid.Row="0"
Grid.Column="3"
IsEditable="True"
MinWidth="250px" />
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- The "Left" Grid -->
<Grid Grid.Column="0"
Background="Aqua">
</Grid>
<GridSplitter HorizontalAlignment="Stretch"
ResizeDirection="Columns"
Width="10"
Grid.Column="1"
ResizeBehavior="PreviousAndNext" />
<!-- The "Right" Grid -->
<Grid Grid.Column="2"
Panel.ZIndex="2"
MinWidth="200"
Background="Yellow">
<Border BorderBrush="Blue"
BorderThickness="1"
MinWidth="200"
Background="#4C808080">
<GroupBox MinWidth="200">
<GroupBox.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0"
Grid.Column="1"
Margin="5" />
</Grid>
</DataTemplate>
</GroupBox.HeaderTemplate>
<Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
SharedSizeGroup="Label" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0"
Grid.Row="0"
Margin="5"
VerticalAlignment="Center"
Grid.ColumnSpan="2" />
<TextBox Grid.Column="1"
Grid.Row="0"
Margin="5,7"
VerticalAlignment="Center"
IsReadOnly="True" />
<Label Grid.Column="0"
Grid.Row="1"
Margin="5"
VerticalAlignment="Center"
Grid.ColumnSpan="2" />
<TextBox Grid.Column="1"
Grid.Row="1"
Margin="5,7"
VerticalAlignment="Center"
IsReadOnly="True" />
<ItemsControl Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
SharedSizeGroup="Label" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0"
Grid.Row="0"
Margin="5"
VerticalAlignment="Center" />
<TextBox Grid.Column="1"
Grid.Row="0"
Margin="5"
VerticalAlignment="Center"
IsReadOnly="True" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</GroupBox>
</Border>
</Grid>
</Grid>
<!--Below grid only shown when errors are present. Not relevant for problem -->
<Grid Grid.Row="2">
<TextBlock />
</Grid>
</Grid>
I changed the Grid "logic" a bit. As I understand you correct you want the GridSplitter for the middle part. Thats why I put the top and bottom part in extra rows to keep them away from the GridSplitter. I had to remove the HorizontalAlignment="Right" from your right Grid, too. Otherwise it would have not changed it's size.
Just to be sure the GridSplitter is working I removed the WebBrowser and added Background colors to the left and right Grid. You can replace that. Thought maybe it would be helpfull for you to see if it's working like expected.
/edit added width relation
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<!-- The "Left" Grid -->
This means when you start the application the first column will take twice the size then the third.
This should be a decent showcase, it's exactly the same for columns, just sideways.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="300"/> //sets the height of the first row
<RowDefinition Height="*"/> //* sets the remainder of the height, doesn't work like auto!
</Grid.RowDefinitions>
<Grid Grid.Row="0"
HorizontalAlignment="Left"
Width="400"
Background="Green" />
<Grid Grid.Row="0"
Margin="400,0,0,0"
Background="Red"/>
<Grid Grid.Row="1"
Background="Blue"/>
<GridSplitter Grid.Row="0"
VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"
Height="2.5"
Background="Black" />
</Grid>

DockPanel LastChildFill resizing to MinWidth?

I try to achieve a simple menubar in WPF.
Here is the XAML:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DockPanel>
<DockPanel Background="Black" VerticalAlignment="Top" LastChildFill="True" DockPanel.Dock="Top" Height="28">
<ToggleButton Content="--" Visibility="Collapsed" />
<StackPanel Orientation="Horizontal">
<Button Content="Add" />
<Button Content="Expand" />
</StackPanel>
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<TextBox Text="Search" MinWidth="80" Width="200" />
<Button Content="X" Margin="0,1,50,0" />
</StackPanel>
</DockPanel>
</DockPanel>
</Page>
It looks good, but when I resize the page to a smaller width, the last child (the Stackpanel with the search textbox) is hiding behind the left items.
Like this:
http://s9.postimage.org/m0tkrobwd/printscreen.png
It would be good if the textbox would resize itself if it has enough space to achieve its MinWidth...Is it possible?
The tricky thing is to give a Control (in your case the SearchTextBox) an alignment but still catch the available space up to MaxWidth. Thanks to this answer.
<DockPanel>
<DockPanel Background="Black" DockPanel.Dock="Top" Height="28">
<ToggleButton DockPanel.Dock="Left" Content="--" Visibility="Collapsed" />
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal">
<Button Content="Add" />
<Button Content="Expand" />
</StackPanel>
<Button DockPanel.Dock="Right" Content="X" />
<Border Name="Container">
<TextBox Text="Search" HorizontalAlignment="Right"
Width="{Binding ElementName=Container, Path=ActualWidth}" MaxWidth="200" />
</Border>
</DockPanel>
</DockPanel>
Container could be another Control too.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition MaxWidth="200" MinWidth="80"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ToggleButton Content="--" Visibility="Collapsed" />
<Button Content="Add" Grid.Column="1"/>
<Button Content="Expand" Grid.Column="2"/>
<TextBox Text="Search" Grid.Column="4"/>
<Button Content="X" Margin="0,1,50,0" Grid.Column="5" />
</Grid>
Instead of giving MaxWidth and MinWidth to TextBox give it to Grid Column.I hope this will help.
Hi Set MaxWidth and MinWidth for the TextBox Not Width. If you will set the Width then it has highest precedence and hence MinWidth won'nt come into act.I hope this will help.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ToggleButton Content="--" Visibility="Collapsed" />
<Button Content="Add" Grid.Column="1"/>
<Button Content="Expand" Grid.Column="2"/>
<TextBox Text="Search" MinWidth="80" MaxWidth="600" Grid.Column="3" ClipToBounds="True" />
<Button Content="X" Margin="0,1,50,0" Grid.Column="4"/>
</Grid>
Its just because of the size of page is not enough for showing both stackpanel on page. for this you can use the minimum size of the page. that will prevent the damages of the control hiding .
and its also up to you what design you want. you can either use grid rather then stackpanles.

Make TextBlock FIT in stack panel so I can make ellipsis

How do I make TextBlock to resize to accomodate only available space in StackPanel?
StackPanel limited to my Grid layout. I just illustrated issue but in my real project it's little more complex, so ideally solution should be simple :)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Grid.Row="1"
Orientation="Horizontal">
<Button Content="Test" />
<TextBlock Text="Test test" />
<Button Content="Test 2" />
<TextBlock Width="Auto">
Some text that I want to trim with ellipse
</TextBlock>
</StackPanel>
</Grid>
You would better make the StackPanel another Grid:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="1" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="Test" />
<TextBlock Grid.Column="1" Text="Test test" />
<Button Grid.Column="2" Content="Test 2" />
<TextBlock Grid.Column="3" Text="Some text that I want to trim with ellipse"/>
</Grid>
</Grid>
I changed your 'main' grid some because it looks odd having only one row and column (starting at index=0) and setting the StackPanel to Grid.Row="1" and Grid.Column="1"
Proper answer is to use DockPanel instead of StackPanel. Last item in DockPanel will be sized to fit remaining space which is exactly what I needed.

"value cannot be null. parameter name current" when trying to drag button

I have couple of buttons on a WPF Window. When I try to drag them I get an following error in dialog box:
value cannot be null. parameter name current
I do not know how to handle it.
Here is my code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Style="{DynamicResource MajourColoumnWidth}"/>
<ColumnDefinition Style="{DynamicResource MinourColoumnWidth}"/>
</Grid.ColumnDefinitions>
<Grid Name="ClinicalDetailsGrid1" >
<Grid.RowDefinitions>
<RowDefinition Style="{DynamicResource RowHeight1}"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Content="Save" Name="btnSave" Grid.Row="0" Grid.Column="0"
VerticalAlignment="Center" VerticalContentAlignment="Center"
HorizontalAlignment="Center" Width="100" Height="20"/>
<Button Content="Bill Payment" Name="btnSave1" Grid.Row="0"
Grid.Column="1" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalAlignment="Center"
Width="100" Height="20"/>
</Grid>
</Grid>

Resources