Left and right alignment leaving space in the middle inside StackPanel - wpf

I have this user control:
And I want to achieve this result:
The XAML of the bottom part is like this:
<StackPanel HorizontalAlignment="left" Orientation="Horizontal">
<TextBox materialDesign:HintAssist.Hint="Filtrar por patente" Width="auto" Margin="5" Text="{Binding Filtro, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left"></TextBox>
<Button Width="120" Style="{DynamicResource MaterialDesignRaisedButton}" Margin="5" HorizontalAlignment="Right" Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}">Volver</Button>
</StackPanel>
I cannot find a way to align textbox to the left and button to the right, leaving a dynamic space in the middle. Button should have fixed width and textbox should be auto.
Thanks

Use a DockPanel. You'll want to stretch it instead of aligning it to the left.
<DockPanel
HorizontalAlignment="Stretch"
>
<TextBox
DockPanel.Dock="Left"
materialDesign:HintAssist.Hint="Filtrar por patente"
Width="auto"
Margin="5"
Text="{Binding Filtro, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left"
/>
<Button
DockPanel.Dock="Right"
Width="120"
Style="{DynamicResource MaterialDesignRaisedButton}"
Margin="5"
HorizontalAlignment="Right"
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
>Volver</Button>
</DockPanel>

Related

WPF left button, centered text, right button in a custom control

I'm trying to prototype a new custom control that has a left button, text, and right button.
The XAML looks like this:
<StackPanel Width="250" Orientation="Vertical" >
<DockPanel Background="Azure" Width="250">
<Button Name="btnLeft" HorizontalAlignment="Left" Width="30" Background="DarkGray" Click="btnAdd_Click" Template="{DynamicResource StandardButtonTemplate1}">
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Previous25px.png" VerticalAlignment="Center" Name="imgLeft"></Image>
</StackPanel>
</Button>
<TextBlock Name="tblkModelType" HorizontalAlignment="Center" Foreground="Black" FontSize="20">Import</TextBlock>
<Button Name="btnRight" HorizontalAlignment="Right" Width="30" Background="DarkGray" Click="btnAdd_Click" Template="{DynamicResource StandardButtonTemplate1}" >
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Next25px.png" VerticalAlignment="Center" Name="imgRight"></Image>
</StackPanel>
</Button>
</DockPanel>
</StackPanel>
The buttons are left and right justified ok, but the (tblkModelType) is left justified right up next to the left button. It doesn't appear that HorizontalAlignment on that tag does anything. If I remove the right button, the TextBlock does center.
Anyone know how to get the buttons on the outside and the TextBlock centered in the Dockpanel? I guess I could use a grid, but it would make the rest of the control more complex.
This should work:
<DockPanel Background="Azure" Width="250" >
<Button DockPanel.Dock="Left" Name="btnLeft" Width="30" Background="DarkGray" Click="btnAdd_Click" Template="{DynamicResource StandardButtonTemplate1}">
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Previous25px.png" VerticalAlignment="Center" Name="imgLeft"></Image>
</StackPanel>
</Button>
<Button DockPanel.Dock="Right" Name="btnRight" Width="30" Background="DarkGray" Click="btnAdd_Click" Template="{DynamicResource StandardButtonTemplate1}" >
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Next25px.png" VerticalAlignment="Center" Name="imgRight"></Image>
</StackPanel>
</Button>
<TextBlock DockPanel.Dock="Top" HorizontalAlignment="Center" Name="tblkModelType" Foreground="Black" FontSize="20">Import</TextBlock>
</DockPanel>
Use DockPanel.Dock to dock btnLeft to the left of the DockPanel, btnRight to the right. Then for tblkModelType set DockPanel.Dock="Top". This will stretch the TextBlock to the entire width of the DockPanel between buttons.
This works for me. As you said your control is more complex, so in case of any problem share more xaml with us.

WPF TextBox will not fill if DockPanel.LastChildFill=true

Why won't my TextBox fill the available space in its DockPanel parent? I expected it to stretch to fill the remaining horizontal space. The Button is attached to the right nicely. I've got this at the top of my Window:
<DockPanel Margin="20,10,20,0" DockPanel.Dock="Top" >
<TextBox TextWrapping="Wrap" Text="{Binding Input}" Background="#FFE4EBFF" Margin="0,0,5,0" />
<Button Content=" _Evaluate" IsDefault="True" HorizontalAlignment="Right" DockPanel.Dock="Right" />
</DockPanel>
The TextBox attaches to the left but is about 5 pixels wide. It's the last child, and has the defaults DockPanel.Dock=Left, HorizontalAlignment=Stretch. I've tried other dock and alignment values without success. Is TextBox an exception to the usual layout rules?
When you set DockPanel.LastChildFill=true
What is the last child you're adding?
The button.
Not the textbox.
Order is top (first) to bottom (last).
I'm not sure exactly what result you want but maybe you just need to make the textbox the last child:
<DockPanel Margin="20,10,20,0" DockPanel.Dock="Top" >
<Button Content=" _Evaluate" IsDefault="True" HorizontalAlignment="Right" DockPanel.Dock="Right" />
<TextBox TextWrapping="Wrap" Text="{Binding Input}" Background="#FFE4EBFF" Margin="0,0,5,0" />
</DockPanel>
This seems to work for me:
<DockPanel Margin="20,10,20,0" DockPanel.Dock="Top" LastChildFill="True">
<Button Content=" _Evaluate" IsDefault="True" HorizontalAlignment="Right" DockPanel.Dock="Right" />
<TextBox TextWrapping="Wrap" Text="{Binding Input}" Background="#FFE4EBFF" Margin="0,0,5,0" />
</DockPanel>

Listbox showing second item first

I am currently sitting on a Silverlight-Listbox and have some
trouble getting my listBox right.
Its (visually) starts from the second item.
I have to scroll up to see the first one.
Why is this happening and how could I fix this?
<ListBox x:Name="ServingsList"
Foreground="White"
Background="#FFB88A8A"
SelectionChanged="servingSelected"
Margin="0,0,0,297">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Height="70" Width="432">
<Rectangle x:Name="Linie"
Fill="#FF8D8D8D"
HorizontalAlignment="Right"
Height="2"
StrokeThickness="0"
VerticalAlignment="Top"
Width="380"
Margin="0,-30,0,0" />
<TextBlock x:Name="ServingTitel"
TextWrapping="Wrap"
Text="{Binding name}"
FontSize="21.333"
Margin="50,-60,0,0" />
<Image x:Name="Ribbon"
HorizontalAlignment="Right"
Height="30"
VerticalAlignment="Top"
Width="151"
Source="/TEX/GrayRibbon.png"
Stretch="UniformToFill"
Margin="0,-60,0,0" />
<TextBlock x:Name="Kcal"
TextWrapping="Wrap"
Text="{Binding kalorien]}"
FontSize="18.667"
Height="23"
Margin="0,-92,8,0"
TextAlignment="Right" />
<Button Content="1"
Width="55" Height="55"
BorderThickness="3"
FontSize="18.667"
Padding="-1,-2,0,0"
Margin="-400,-87,0,0"
FontWeight="Bold"
Click="servingButtonClicked" />
</StackPanel>
</DataTemplate>
</ListBox>
You need to check your Margin values - in the main list you're putting 297 pixels of whitespace below your list box. Other elements have weird values too. Expression Blend sometimes messes with the Margins if you change from a StackPanel to a Grid.
e.g:
Margin="0,0,0,297">

Why won't the WPF progressbar stretch to fit?

This is my original code:
<StackPanel Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal">
<ProgressBar Height="23" Name="searchProgressBar" Foreground="Blue" BorderBrush="#00000000" BorderThickness="1" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
<TextBlock Text="asdf" Height="23" Name="progressTextBlock" VerticalAlignment="Top" Foreground="Red" HorizontalAlignment="Right"/>
</StackPanel>
The progressbar was very small, maybe 2 or 3 pixels wide, then there was the text block and empty space after. So I tried explicitly docking the elements to sides:
<DockPanel Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" >
<ProgressBar DockPanel.Dock="Left" Height="23" Name="searchProgressBar" Foreground="Blue" BorderBrush="#00000000" BorderThickness="1" VerticalAlignment="Top" />
<TextBlock DockPanel.Dock="Right" Text="asdf" Height="23" Name="progressTextBlock" VerticalAlignment="Top" Foreground="Red" HorizontalAlignment="Right"/>
</DockPanel>
No avail. I also tried modifying each solution by setting HorizontalAlignment="Stretch" on the progress bar, but there's no change. How do i stretch it to fill all the space there is after the text block has been rendered?
Remove DockPanel.Dock="Left" from the ProgressBar and switch the order of the controls:
<DockPanel>
<TextBlock DockPanel.Dock="Right" Height="23" VerticalAlignment="Top" HorizontalAlignment="Right"/>
<ProgressBar Height="23" VerticalAlignment="Top" />
</DockPanel>
By default, DockPanel has its property LastChildFill set to true, which will make the ProgressBar take the available space.
ahh I see what you're trying to do. This is probably a better place to use a grid with 2 column definitions. The first(the left one) columndefinition with Width="*" and the second(the right one) with a width set to Width="Auto". For more info about auto vs * see http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/9a7e6591-1fae-4295-b68a-be97e8e53d06/

Align label to the middle of dock panel

I have a dock panel, with one label in the middle and another button on the far right.
Because of the button the label cannot align to the middle when the windows is maximized.
WPF:
<DockPanel Height="40" HorizontalAlignment="Stretch" Margin="-1,-2,0,0" Name="dockPanel1" VerticalAlignment="Stretch" Width="Auto" OpacityMask="{x:Null}">
<Label FontSize="18" Content="Sales" FontWeight="Bold" FontFamily="Arial" Width="883" Height="42" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Foreground="White" DockPanel.Dock="Left" VerticalAlignment="Center" VerticalContentAlignment="Center"></Label>
<Button FontSize="18" Height="47" Width="123" Name="btnStart" Foreground="White" BorderBrush="{x:Null}" FlowDirection="LeftToRight" HorizontalContentAlignment="Center" FontFamily="Arial Rounded MT" ClickMode="Press" DockPanel.Dock="Right" HorizontalAlignment="Right" VerticalAlignment="Center" Padding="0" Content="Start" BorderThickness="0" Focusable="False">
</DockPanel>
Use a Grid instead of a DockPanel
Grid's allow objects to be placed on top of each other, so you can position your Label in the middle and the Button on the Right
<Grid>
<Label HorizontalAlignment="Center" VerticalAlignment="Center" />
<Button HorizontalAlignment="Right" />
</Grid>
Also if you're new to WPF's Layouts, I'd recommend reading through WPF Layouts: A Quick Visual Start so you know what layouts are available and can pick the best one for your sitaution

Resources