WPF - Two Columns align right column - wpf

I have the following XAML, which I have tried to simplify and removed irrelevant code such as name, content, bindings etc.
The problem is that the textbox on the right is not very nicely aligned. I expect the textboxes to be aligned so they are of equal width.
XAML code:
<StackPanel Grid.Row="1" Grid.RowSpan="2" Grid.Column="1" MinWidth="200" HorizontalAlignment="Right">
<GroupBox >
<GroupBox.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" Margin="5"/>
</Grid>
</DataTemplate>
</GroupBox.HeaderTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="69"/>
<ColumnDefinition Width="6"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Margin="5" VerticalAlignment="Center" Grid.ColumnSpan="2"/>
<TextBox Grid.Column="2" Grid.Row="0" Margin="5,7" VerticalAlignment="Center"/>
<Label Grid.Column="0" Grid.Row="1" Margin="5" VerticalAlignment="Center" Grid.ColumnSpan="2"/>
<TextBox Grid.Column="2" Grid.Row="1" Margin="5,7" VerticalAlignment="Center"/>
<ItemsControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<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"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</GroupBox>
</StackPanel>
I have tried a lot of different combinations but can't get it to as I want for my end goal.

You can specify on the Grid above the Itemscontrol: Grid.IsSharedSizeScope='True'.
Then, in the DataTemplate for item, specify on the first ColumnDefinition:
SharedSizeGroup='LabelsColumn(or any name you like)'.
That will recalculate automatically the width of the first column, to be as long as the longest text/Label(in this scenario).
Example:
<StackPanel Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="1"
MinWidth="200"
HorizontalAlignment="Right">
<GroupBox>
<GroupBox.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</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="Labels"/>
<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" />
<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" />
<ItemsControl Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="3">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
SharedSizeGroup="Labels"/>
<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" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</GroupBox>
</StackPanel>

Related

WPF VerticalAlignment="Top" is not working

I'm creating a table presentation out of WPF grid system. I can create the table though but my issue in the Merchandise portion is, as the Non-Merchandise grow taller, the data in Merchandise will vertically center even if I already set VerticalAlignment="Top". The same issue with the Tender column. See the following image showing result.
<Grid Grid.Column="0" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="250" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="0" Background="Aqua">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Merchandise" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Center" VerticalAlignment="Top" />
<TextBlock Text="Amount" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Margin="5" />
<TextBlock Text="Sales" Grid.Row="2" Grid.Column="0" VerticalAlignment="Top" />
<TextBlock Text="25,887.22" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Top" />
</Grid>
<Grid Grid.Column="1" Grid.Row="0" Background="Aquamarine">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Non-Merchandise" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Center" />
<TextBlock Text="Type" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" Margin="5"/>
<TextBlock Text="Amount" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Margin="5"/>
<TextBlock Text="Gift Card" Grid.Row="2" Grid.Column="0" />
<TextBlock Text="Gift Card" Grid.Row="3" Grid.Column="0" />
<TextBlock Text="Gift Card" Grid.Row="4" Grid.Column="0" />
<TextBlock Text="Gift Card" Grid.Row="5" Grid.Column="0" />
<TextBlock Text="Gift Card" Grid.Row="6" Grid.Column="0" />
<TextBlock Text="Gift Card" Grid.Row="7" Grid.Column="0" />
</Grid>
<Grid Grid.Column="2" Grid.Row="0" Background="AliceBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Tender" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" HorizontalAlignment="Center" />
<TextBlock Text="Description" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" Margin="5"/>
<TextBlock Text="Begin Amt" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Margin="5"/>
<TextBlock Text="Trx Amt" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Right" Margin="5"/>
<TextBlock Text="Removed" Grid.Row="1" Grid.Column="3" HorizontalAlignment="Right" Margin="5"/>
</Grid>
</Grid>
A simple trick is to add an extra row at the bottom and set Height="*" while setting existing rows Height="Auto". That way, existing rows will be pushed up to the top.
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

Remove lines between rows in WPF grid

I have the following XAML in a WPF application. There are white horizontal lines between the rows. Is there anything that can be done to remove them?
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="Header" Height="Auto"/>
<RowDefinition x:Name="Body" Height="1*"/>
<RowDefinition x:Name="Footer" Height=".5*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".4*"/>
<ColumnDefinition />
<ColumnDefinition Width=".4*"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="1" Background="#454d52"/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontSize="54" Text="" Padding="200,30,200,30"/>
</Grid>
<Grid Grid.Row="1">
<Border BorderThickness="0" Background="#FF454D52"/>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="24" Foreground="White" Padding="50,0,0,0"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24" Foreground="White"/>
<Label HorizontalAlignment="Right" VerticalAlignment="Center" FontSize="24" Foreground="White" Padding="0,0,50,0"></Label>
</Grid>
</Grid>
</Grid>
Set SnapsToDevicePixels on your top-most Grid:
<Grid SnapsToDevicePixels="True">

Tab-shaped border needs clipping

I have a spec for an application with three columns where the central one bows in into an inverted tab shape.
I have the basics figured out:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="371*"></ColumnDefinition>
<ColumnDefinition Width="469*"></ColumnDefinition>
<ColumnDefinition Width="371*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="83*"></RowDefinition>
<RowDefinition Height="309*"></RowDefinition>
<RowDefinition Height="223*"></RowDefinition>
<RowDefinition Height="67*"></RowDefinition>
</Grid.RowDefinitions>
<TextBox Background="Transparent" Grid.Row="0"
Text="Foo" HorizontalAlignment="Center" VerticalAlignment="Center" >
</TextBox>
<Border Grid.Row="0" BorderBrush="Red" BorderThickness="0,0,0,4"></Border>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="221*"></RowDefinition>
<RowDefinition Height="171*"></RowDefinition>
<RowDefinition Height="290*"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
</Grid>
<Border Grid.Row="0" BorderBrush="Red" BorderThickness="4,0,4,4" CornerRadius="50" >
</Border>
</Grid>
</Grid>
But the inverted tab border is in need of clipping about 60% of the way down. I can of course position an element on top of it but that seems like the wrong solution and I'd like to avoid it.
I've looked at the Border.Clip property but can't quite figure out how to work with it nor find much in the way of documentation. What do I need to do here?
There's a bunch of different ways you can accomplish this, some will be more appropriate for potential resizing considerations than others etc. Here's just a few potential solution examples.
<StackPanel>
<!-- added -->
<Grid Background="LightBlue" Height="100">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="2"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Grid.ColumnSpan="3"
Fill="DarkBlue"/>
<Rectangle Grid.Row="1" Grid.ColumnSpan="3"
Fill="Yellow"/>
<Border Grid.Row="1" Grid.RowSpan="2" Grid.Column="1"
Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="2,0,2,2"
CornerRadius="0,0,20,20"/>
</Grid>
<!-//-->
<Grid Background="LightBlue" Height="100">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Grid.ColumnSpan="3"
Fill="DarkBlue"/>
<Rectangle Grid.ColumnSpan="3" VerticalAlignment="Bottom" Height="2"
Fill="Yellow"/>
<Border Grid.Row="1" Grid.RowSpan="2" Grid.Column="1"
Background="DarkBlue" Margin="0,-2,0,0"
BorderBrush="Yellow" BorderThickness="2,0,2,2"
CornerRadius="0,0,20,20"/>
</Grid>
<!-- Or another, or another, or another... -->
<Grid Background="LightBlue" Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="3" Height="50"
VerticalAlignment="Top" Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="0,0,0,2"/>
<Border Grid.Column="1" Height="80" CornerRadius="20"
VerticalAlignment="Top" Background="DarkBlue" BorderThickness="2,0,2,2">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="DarkBlue" Offset="0.6"/>
<GradientStop Color="#FFFFFF00" Offset="0.6"/>
</LinearGradientBrush>
</Border.BorderBrush>
</Border>
</Grid>
<Grid Background="LightBlue" Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.Column="1" Height="80" CornerRadius="20"
VerticalAlignment="Top" Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="2,0,2,2"/>
<Border Grid.ColumnSpan="3" Height="50"
VerticalAlignment="Top" Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="0,0,0,2"/>
<Rectangle Grid.Column="1" Height="51" Margin="2,0"
VerticalAlignment="Top" Fill="DarkBlue"/>
</Grid>
<Grid Background="LightBlue" Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="3" Height="50"
VerticalAlignment="Top" Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="0,0,0,2"/>
<Border Grid.Column="1" Height="80" CornerRadius="20"
VerticalAlignment="Top" Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="2,0,2,2"
Clip="M0,47.7 L175,47.7 L175,80 L0,80 z"/>
</Grid>
</StackPanel>
CornerRadius has a constructor that can take 4 values for the radius of each corner: top-left, top-right, bottom-right, bottom-left.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="9*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Background="Transparent" Grid.Row="0" Grid.Column="0"
Text="Foo" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Border Grid.Row="1" Grid.Column="1" BorderBrush="Red" BorderThickness="4,0,4,4" CornerRadius="0, 0, 50, 50" />
</Grid>
Another option (probably the one I would choose) is to use a TabControl, put the tab on the bottom and center it.
<TabControl TabStripPlacement="Bottom" Background="DarkBlue" BorderBrush="Yellow" Margin="3" >
<TabControl.Resources>
<Style TargetType="{x:Type TabPanel}">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</TabControl.Resources>
<TabItem Header="Test" Background="DarkBlue" BorderBrush="Yellow" Foreground="Yellow" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Grid.Row="1" Text="Foo" />
</Grid>
</TabItem>
</TabControl>

Gridsplitter does not allow user to resize grid

My code is as follows:
<Grid
ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"></ColumnDefinition>
<ColumnDefinition Width="5"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<GridSplitter
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
Width="5"
Background="Purple"
HorizontalAlignment="left" />
<ListBox
Grid.Row="0"
Grid.Column="0"
ItemsSource="{Binding Tests}"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
Grid.IsSharedSizeScope="True">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="10*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock
Text="{Binding Name}"
Grid.Column="0">
</TextBlock>
<Image
Grid.Column="1">
</Image>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock
Grid.Row="0"
Grid.Column="1"
Text="{Binding CommandPromptOutput}">
</TextBlock>
<Button
Grid.Row="1"
Grid.Column="2"
Content="Run" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" HorizontalAlignment="Stretch" />
</Grid>
The grid splitter is showing up but it has no control over resizing anything.
I have also tried adding:
<GridSplitter
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
Width="5"
Background="Purple"
HorizontalAlignment="left"
ResizeDirection="Columns"
ResizeBehavior="PreviousAndNext" />

WPF Alignment problems

I have this window:
My problem is that when the number is larger than 2 digits, it pushes the red rectangle to
the right. and I would like it to act like that:
The rectangle must not been pushed to the right.
This is my XAML:
<StackPanel>
<Border BorderThickness="1" BorderBrush="Beige">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="1">
<TextBlock Text="1" VerticalAlignment="Top" />
<Rectangle Width="20" Height="20" Fill="Red" VerticalAlignment="Top" />
</StackPanel>
</Grid>
</Border>
<Border BorderThickness="1" BorderBrush="Beige">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="1" >
<TextBlock Text="1123" VerticalAlignment="Top" />
<Rectangle Width="20" Height="20" Fill="Red" VerticalAlignment="Top" />
</StackPanel>
</Grid>
</Border>
</StackPanel>
<StackPanel>
<Border BorderThickness="1" BorderBrush="Beige">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="1" VerticalAlignment="Top" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Right"/>
<Rectangle Width="20" Height="20" Fill="Red" Grid.Column="1" Grid.Row="0"/>
<TextBlock Text="1123" VerticalAlignment="Top" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Right"/>
<Rectangle Width="20" Height="20" Fill="Red" Grid.Column="1" Grid.Row="1"/>
</Grid>
</Border>
</StackPanel>

Resources