DockPanel LastChildFill resizing to MinWidth? - wpf

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.

Related

WPF How to make control resize relative to next control

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.

Why doesn't a textbox stretch inside stackpanel WPF?

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="49*" />
<ColumnDefinition Width="25*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Margin="30" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0,0,5,0" Text="Username:" />
<TextBox HorizontalAlignment="Stretch"/>
</StackPanel>
</StackPanel>
--Result image--
Im trying to make it so that the textbox will fill the rest of the space inside the current StackPanel.
however the "Stretch" propety doesn't seem to work - why is that?
Is there a different way do it or what am I doing wrong?
A StackPanel always tries to achieve the minimum possible height/width, depending on orientation; therefore, Stretch has no effect. You might want to use a DockPanel instead, which allows children to stretch:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="49*" />
<ColumnDefinition Width="25*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1"
Margin="30"
VerticalAlignment="Center">
<DockPanel>
<TextBlock DockPanel.Dock="Left" Margin="0,0,5,0"
Text="Username:" />
<TextBox HorizontalAlignment="Stretch"/>
</DockPanel>
</StackPanel>
</Grid>

Can we move Grid Splitter On Left like we drag it on button click in wpf?

<Grid>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Button Content="◄" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Button Content="►" HorizontalAlignment="Right" VerticalAlignment="Top"/>
</StackPanel>
<Grid Height="245">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--Declaring Label-->
<DockPanel LastChildFill="False" Background="Yellow">
<Label Content="Left" Grid.Column="0" DockPanel.Dock="Left" />
</DockPanel>
<!--Splitter Code-->
<GridSplitter HorizontalAlignment="Right" VerticalAlignment="Stretch" Grid.Column="1" ResizeDirection="Columns"
Background="Black" ResizeBehavior="PreviousAndNext" Width="10"/>
<!--Declaring Label-->
<Label Content="Right" Grid.Column="2" Background="Pink"/>
</Grid>
</StackPanel>
</Grid>
I want to drag Grid Splitter on button Click. I tried Double Animation.StoryBoard which works on grid but not grid splitter.
[]1
You have to resize grid columns, not gridsplitter.
private void BtnLeft_Click(object sender, RoutedEventArgs e)
{
MyGrid.ColumnDefinitions[0].Width = new GridLength(100);
}
<Grid x:Name="MyGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Content="Left" Background="LightBlue" />
<GridSplitter Grid.Column="1" Width="10" ResizeBehavior="PreviousAndNext" />
<Label Content="Right" Background="LightGoldenrodYellow" Grid.Column="2" />
<Button Content="Left" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnLeft_Click" />
</Grid>

WPF – How to set shortcut for custom button (image and TextBlock)

I Have a little WPF window that contains 3 buttons with image and TextBlock like this :
<Button x:Name="cmdPrint" Margin="5" VerticalAlignment="Center" Grid.Column="2"
ToolTip="Print a simulation"
MouseMove="MouseMouveHandler"
Click="ButtonClickHandler" Height="36">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="70"/>
</Grid.ColumnDefinitions>
<Image Source="images\print.png" Grid.Column="0" VerticalAlignment="Center"
Margin="2"/>
<TextBlock Text="_Print" Grid.Column="1" Foreground="DarkBlue"
VerticalAlignment="Center" Margin="2"/>
</Grid>
</Button>
As you can see , the button is customized, so, the following code doesn’t work :
<Button Name="cmdPrint " Content="_Print"></Button>
Is it possible to Fire Print button when i Press ‘P’ key ?
Thank you in advance.
Use label instead of text block will work for you
Click="ButtonClickHandler" Height="36" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="70"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" VerticalAlignment="Center"
Margin="2"/>
<Label Content="_Print" Grid.Column="1" Foreground="DarkBlue"
VerticalAlignment="Center" Margin="2" />
</Grid>
</Button>

Make ComboBox stretch to available space with maxwidth and right-aligned parent

I'm having a problem achieving the layout i want.
This is my code:
<DockPanel DockPanel.Dock="Bottom" HorizontalAlignment="Right" LastChildFill="True">
<Label DockPanel.Dock="Left" Content="Add new:"/>
<Button DockPanel.Dock="Right" Content="Add" VerticalAlignment="Center"/>
<ComboBox VerticalAlignment="Center" MaxWidth="150" HorizontalAlignment="Stretch">
<System:String>Item1</System:String>
<System:String>Item2</System:String>
<System:String>Item3</System:String>
</ComboBox>
</DockPanel>
What I want is to have the three elements aligned to the right, in the order Label, ComboBox, Button. The Label and the button should take as much space as needed, but I want the ComboBox to take as much space as possible up to 150 px.
It kind of works when the DockPanel is not set to HorizontalAlignment=Right.
Any tips/solutions?
Thanks.
Use the RightToLeft setting, like this:
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid FlowDirection="RightToLeft">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition MaxWidth="150"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label FlowDirection="LeftToRight" Grid.Column="2" Content="Add new:"/>
<ComboBox FlowDirection="LeftToRight" Grid.Column="1" VerticalAlignment="Center" MaxWidth="150" HorizontalAlignment="Stretch">
<ComboBoxItem>Test</ComboBoxItem>
<ComboBoxItem>Test</ComboBoxItem>
<ComboBoxItem>Test</ComboBoxItem>
</ComboBox>
<Button FlowDirection="LeftToRight" Grid.Column="0" DockPanel.Dock="Right" Content="Add" VerticalAlignment="Center"/>
</Grid>
</Grid>
Here is is running:

Resources