WPF alignment inside StatusBar - wpf

I want to have Image which in centered inside StatusBar and DockPanel which is align to right in StatusBar
<StatusBar VerticalAlignment="Bottom" Height="30">
<StatusBarItem HorizontalAlignment="Center" >
<Image />
</StatusBarItem>
<StatusBarItem HorizontalAlignment="Right">
<StackPanel Orientation="Horizontal">
<TextBlock />
<Controls:ProgressRing />
</StackPanel>
</StatusBarItem >
</StatusBar>
I have above code unfortunately it's not working , StackPanel is correctly alight to right but Image is alight to left...

The StatusBar uses a DockPanel to position the StatusBarItems which is not very convenient when you have several items.
To circumvent your issue, you can create your own layout in the ItemsPanelTemplate, for instance, a 3 columns Grid:
Place your image in the center of the middle column, and place your custom control on the right of the 3rd column.
<StatusBar VerticalAlignment="Bottom" Height="30">
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
<StatusBarItem Grid.Column="1" HorizontalAlignment="Center">
<Image />
</StatusBarItem>
<StatusBarItem Grid.Column="2" HorizontalAlignment="Right">
<StackPanel Orientation="Horizontal">
<TextBlock />
<Controls:ProgressRing />
</StackPanel>
</StatusBarItem >
</StatusBar>

Related

WPF XAML: place Image near TextBlock but align text to center of row

I have a similar structure in a WPF app:
<Grid Background="White">
<StackPanel>
<TextBlock Text="1234567" FontSize="18" FontWeight="Bold" Height="25" TextAlignment="Center"/>
<Line X1="0" Y1="0" X2="160" Y2="0" Stroke="Gray" StrokeThickness="2"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Width="25" Height="25" Grid.Column="0" Source="img.png" />
<TextBlock Grid.Column="1" Text="3456789" FontSize="18" FontWeight="Bold" Height="25" TextAlignment="Center"/>
</Grid>
</StackPanel>
This results in the following layout:
Is there any way to place the bottom text in the center of the row, so it's alignment would match with the text above?
Or is there a solution to place the image on top of the bottom row on the left side without column definitions?
Thanks
Use a single-cell grid with different alignments. You will run the risk of long text being under the image, and you will have to set a Width value on the StackPanel. See the HorizontalAlignment flag below:
<Grid>
<TextBlock Text="3456789" FontSize="18" FontWeight="Bold" Height="25" HorizontalAlignment="Center"/>
<Image Width="25" Height="25" Source="img.png" HorizontalAlignment="Left" />
</Grid>

How can I turn on both vertical and horizontal borders for the itemTemplate Control?

I created the item template control and set its border thickness and color in Data Template. This is my ItemTemplate code:
<ItemsControl x:Name="VimshottariDasha" Margin="-10,83,-124,-267" FontSize="16" Grid.ColumnSpan="3" BorderThickness="0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="DimGray">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Col1" />
<ColumnDefinition SharedSizeGroup="Col2" />
<ColumnDefinition SharedSizeGroup="Col3" />
</Grid.ColumnDefinitions>
<Button Background="Transparent" BorderThickness="0" x:Name="DashaButton" Grid.Column="0" Content="{Binding rulerName}" Command="{Binding SelectedDasha}" CommandParameter="{Binding Content, RelativeSource={RelativeSource Self}}"/>
<TextBlock Grid.Column="1" Text="{Binding rulerStartDate, StringFormat=dd-MMM-yyyy HH:mm:ss}" />
<TextBlock Grid.Column="2" Text="{Binding rulerEndDate, StringFormat=dd-MMM-yyyy HH:mm:ss}"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
How do I show both vertical and horizontal borders regardless of stack orientation?
The same thing happens in another itemTemplate but in reverse, whose stack orientation is set to Horizontal. I can see vertical borders in the second item Control but no Horizontal borders.
This is the current Output, it has horizontal Borders inside but no vertical ones(Stack orientation is vertical by default)
This is second ItemControl with horizontal stack orientation it is missing horizontal borders.
Thanks.
First go through this link to understand how to add border around TextBlock.
You can also use Label instead of TextBlock to add border.
Now look into modified code:
ItemsControl Grid.Row="0" x:Name="VimshottariDasha" Margin="10" FontSize="16" Grid.ColumnSpan="3" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<!--<Border BorderThickness="1" BorderBrush="DimGray">-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Col1" />
<ColumnDefinition SharedSizeGroup="Col2" />
<ColumnDefinition SharedSizeGroup="Col3" />
</Grid.ColumnDefinitions>
<Button Background="Transparent" BorderThickness="1" x:Name="DashaButton" Grid.Column="0" Content="{Binding rulerName}" />
<Border Grid.Column="1" BorderThickness="1" BorderBrush="Blue">
<TextBlock Text="{Binding rulerStartDate, StringFormat=dd-MMM-yyyy HH:mm:ss}" />
</Border>
<Label BorderThickness="1" BorderBrush="Bisque" Grid.Column="2" Content="{Binding rulerEndDate, StringFormat=dd-MMM-yyyy HH:mm:ss}"/>
</Grid>
<!--</Border>-->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
A WPF Border control only draws the border along its outer edges. [It is possible to turn of one or more edges by setting its BorderThickness.]
If you want to create border lines between individual controls, you either have to use multiple Border elements, or manually draw the internal lines yourself.
For example
<Border HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="Green" BorderThickness="2" >
<Grid Height="24" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Column 1" VerticalAlignment="Center" />
<TextBlock Grid.Column="2" Text="Column 2" VerticalAlignment="Center" />
<TextBlock Grid.Column="4" Text="Column 3" VerticalAlignment="Center" />
<Path Stroke="Red" StrokeThickness="1" Data="M 0,0 M 2,2 M 1,0 L 1,2" Stretch="Fill" Grid.Column="1" />
<Path Stroke="Red" StrokeThickness="1" Data="M 0,0 M 2,2 M 1,0 L 1,2" Stretch="Fill" Grid.Column="3" />
</Grid>
</Border>

Gridsplitter in statusbar

I am attempting to put grid splitters in a statusbar. I have overridden the item panel template to place a grid in the status bar. I want to be able to slide the grid columns back and forth. Unfortunately I can't get the grid splitters to appear. I am using the xaml code below. Thanks for your time in advance.
<StatusBar>
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<Grid IsItemsHost="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
<StatusBarItem Grid.Column="0">
<Label Content="blah" />
</StatusBarItem>
<StatusBarItem Grid.Column="1">
<GridSplitter Width="10" HorizontalAlignment="Stretch" />
</StatusBarItem>
<StatusBarItem Grid.Column="2">
<Label Content="blah1" />
</StatusBarItem>
<StatusBarItem Grid.Column="3">
<GridSplitter Width="10" HorizontalAlignment="Stretch" />
</StatusBarItem>
<StatusBarItem Grid.Column="4">
<Label Content="blah2" />
</StatusBarItem>
<StatusBarItem Grid.Column="5">
<GridSplitter Width="10" HorizontalAlignment="Stretch" />
</StatusBarItem>
<StatusBarItem Grid.Column="6">
<Label Content="blah3" />
</StatusBarItem>
</StatusBar>
Your GridSplitter is not a direct descendant of the Grid. It is wrapped in a StatusBarItem. Therefore this can't work in that configuration.
You could just use a Grid instead and style the background and borders to make it look like a StatusBar. The StatusBar is a relatively simple looking control, so it shouldn't be a too big of a deal to make something that looks like it.

WPF: why is the button stays on the left side?

I have this WPF button in my StackPanel:
<StackPanel Grid.ColumnSpan="6" Grid.Row="12" Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Center" Background="LightGray" Height="40">
<Button x:Name="btnSave" Click="btnSave_Click" Content="{x:Static res:Strings.ToolPanelEditView_Button_Save}" HorizontalAlignment="Right" />
</StackPanel>
For some reason, the button shows on the left although I set its HorizontalAlignment to Right:
How can I make my save button show on the right?
P.S. when I change the StackPanel's HorizontalAlignment to Right instead of Stretch, the button does show on the right like it should (but then the gray background of the StackPanel does not stretch either...
I think that a Grid is more appropriate for your case
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center" Background="LightGray" Height="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button x:Name="btnSave" Grid.Column="1" Content="Save" HorizontalAlignment="Right" />
<!--Your Other Button Grid.Column="2"-->
</Grid>
or you could as well replace the stackPanel with a DockPanel
You can use DockPanel as container, stretch it and dock your button to the right side
<DockPanel Grid.ColumnSpan="6" Grid.Row="12" HorizontalAlignment="Stretch" VerticalAlignment="Center" Background="LightGray" Height="40">
<Button Content="Save" DockPanel.Dock="Right"/>
<Button Content="Cancel" DockPanel.Dock="Right"/>
</DockPanel>

WPF Statusbar, stretch textblock to take as much space as possible

I created my own simple statusbarcontrol with 3 TextBlocks. Now I would like that the first Textblock takes as much space as it has available. That I don't seem to get done.. Now it only takes the space needed to display the text.
XAML:
<StatusBar Background="{StaticResource GradientBrush}">
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
<StatusBarItem HorizontalAlignment="Left"
HorizontalContentAlignment="Right">
<Border BorderThickness="1"
BorderBrush="Black"
Padding="5 0 5 0"
Background="White">
<TextBlock Text="{Binding Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Foreground="{Binding TextColorMessage}"
Background="White"
/>
</Border>
</StatusBarItem>
<Separator Grid.Column="1" />
<StatusBarItem Grid.Column="2"
HorizontalAlignment="Right">
<TextBlock Text="{Binding Path=DatabaseName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</StatusBarItem>
<Separator Grid.Column="3" />
<StatusBarItem Grid.Column="4"
HorizontalAlignment="Right">
<TextBlock Text="{Binding Path=ComputerName}" />
</StatusBarItem>
Well this is pretty straight forward:
you had set the StatusBarItem HorizontalAlignment="Left" when it should be "strech", same for the HorizontalContentAlignment.
Also would suggest setting margin=0 on the border.
this is what i did so it will work for me:
<StatusBarItem HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch">
<Border BorderThickness="1"
BorderBrush="Black"
Margin="0"
Padding="5 0 5 0"
Background="White">
<TextBlock Text="{Binding Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Foreground="{Binding TextColorMessage}"
Background="White"/>
</Border>
</StatusBarItem>
if this is helpful please mark as answer
Try setting the StatusBarItem's HorizontalAlignment and HorizontalContentAlignment to Stretch.
Set the StatusBarItem's HorizontalContentAlignment to Stretch and the TextBlock's TextAlignment property to Right. (This second setting is only needed for the first StatusBarItem as it seems that you try to align the text to the right in it.)
StatusBar has only one HorizontalAlignment=Right item to effect, so you can get only the last item in wanted place. You can set statusBar's FlowDirection="RightToLeft" and add item in reversed order. Details: right placed items needn't StatusBarItem surrounded, but the left one need to be streched. Following code:
<StatusBar VerticalAlignment="Bottom" FlowDirection="RightToLeft"><!--flow right to left cause items right aligned-->
<!--make item's flow back left to right, avoid display disorder-->
<TextBlock x:Name="textBlock_status_R1" Text="111.147.168.20" Grid.Column="2" Margin="10,0" FlowDirection="LeftToRight"/>
<Separator/>
<TextBlock x:Name="textBlock_status_R2" Text="Working" Margin="10,0" FlowDirection="LeftToRight"/>
<Separator/>
<!--To fill rest space,need StatusBarItem packing and default HorizontalAlignment="Stretch"-->
<StatusBarItem FlowDirection="LeftToRight">
<TextBlock x:Name="textBlock_status_L1" Text="Information here."/>
</StatusBarItem>
</StatusBar>

Resources