How to bind a line's length to a row's height? - wpf

I added a line but i don't know how to set it's location .(Now I just leave it in a canvas) What i'd like to do is binding the lines length = the first row's height(Auto now).
<DataTemplate DataType="{x:Type vm:SettingsViewModel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Border Grid.Row="0" Margin="0,0,0,0" >
<!--
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="White"/>
<GradientStop Offset="1" Color="LightGray"/>
</LinearGradientBrush>
</Grid.Background>-->
<Grid>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="0.1*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Background="AliceBlue" BorderThickness="0"></TextBox>
<Border Background="AliceBlue" Grid.Column="1">
<Image Source="/Images/search.png" ></Image>
</Border>
<Canvas Grid.Column="2">
<Line X1="0" Y1="0" X2="0" Y2="10" Stroke="Black"/>
</Canvas>
</Grid>
</Border>
<TreeView Style="{StaticResource ResourceKey=SearchableTreeView}" ItemsSource="{Binding Path=Roots, Mode=OneWay}" Background="Transparent" Grid.Row="1"/>
</Grid>
</DataTemplate>

If you just want a seperator, why dont use a Rectangle instead of Line
<Grid>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="0.1*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Background="AliceBlue" BorderThickness="0"></TextBox>
<Border Background="AliceBlue" Grid.Column="1">
<Image Source="/Images/search.png" ></Image>
</Border>
<Rectangle Grid.Column="2" VerticalAlignment="Stretch" Width="1" Margin="2" Stroke="Black" />
</Grid>

Related

C# WPF If two Rectangles with different background colors overlap completely, the border of the Rectangele below will appear

I use Rectangle and button to do the test, but the results are not the same
I want to overlap two rectangles of different colors, and i don't want see the rectangle below, but this is not the case.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Border BorderBrush="Black" BorderThickness="1" Grid.Row="1" Grid.Column="1">
<Border>
<Canvas x:Name="Pad">
<Rectangle Height="100"
Width="100"
Fill="Red"
Canvas.Left="10"
ClipToBounds="True"
Canvas.Top="10"
>
</Rectangle>
<Rectangle Height="100"
Width="100"
Fill="White"
Canvas.Left="10"
Canvas.Top="10">
</Rectangle>
</Canvas>
</Border>
</Border>
</Grid>
If I use two buttons to overlap, I will not see the border below. Why is the result of using rectangle and button different ?
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Border BorderBrush="Black" BorderThickness="1" Grid.Row="1" Grid.Column="1">
<Border>
<Canvas x:Name="Pad">
<Button Height="100"
Width="100"
BorderThickness="0"
Background="Red"
Canvas.Left="10"
ClipToBounds="True"
Canvas.Top="10">
</Button>
<Button Height="100"
Width="100"
Background="White"
BorderThickness="0"
Canvas.Left="10"
Canvas.Top="10">
</Button>
</Canvas>
</Border>
</Border>
</Grid>
I use SnapsToDevicePixels="True" to solve the problem
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Border BorderBrush="Black" BorderThickness="1" Grid.Row="1" Grid.Column="1">
<Border>
<Canvas x:Name="Pad">
<Rectangle Height="100"
Width="100"
Fill="Red"
Canvas.Left="10"
ClipToBounds="False"
SnapsToDevicePixels="True"
Canvas.Top="10">
</Rectangle>
<Rectangle Height="100"
Width="100"
Fill="White"
SnapsToDevicePixels="True"
Canvas.Left="10"
Canvas.Top="10">
</Rectangle>
</Canvas>
</Border>
</Border>
</Grid>
Update
The result after use:
The problem seem to go away if ClipToBounds="False" is set for both Rectangles.

Row height don't include scrollviewer ability

I'm currently creating a new WPF window which look like this :
The part starting with "Filter and with the array is define like this :
<Grid Grid.Row="2" Visibility="{Binding FilterVisibility}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Margin="20,0,0,0" HorizontalAlignment="Left"
Text="{Binding Source={x:Static dictionnaries:MainDictionnary.bcfFilter}, StringFormat={}{0} :}"/>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="150"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ItemsControl Grid.Column="1" Margin="2" Grid.IsSharedSizeScope="True"
ItemsSource="{Binding Filters}">
<ItemsControl.Template>
<ControlTemplate>
<Border Background="White" BorderBrush="Black" BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="col1"/>
<ColumnDefinition Width="1" SharedSizeGroup="marg"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="col2"/>
<ColumnDefinition Width="1" SharedSizeGroup="marg"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="col3"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Static dictionnaries:MainDictionnary.filterField}"
Grid.Column="0"
Margin="5,2"/>
<Line Grid.Column="1"
Y2="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Self}}"
Stroke="Gray"
HorizontalAlignment="Center"/>
<TextBlock Text="{x:Static dictionnaries:MainDictionnary.filterCondition}"
Grid.Column="2" Margin="5,2"
TextWrapping="WrapWithOverflow" TextAlignment="Center"/>
<Line Grid.Column="3"
Y2="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Self}}"
Stroke="Gray"
HorizontalAlignment="Center"/>
<TextBlock Text="{x:Static dictionnaries:MainDictionnary.filterValue}"
Grid.Column="4" Margin="5,2"
TextWrapping="WrapWithOverflow" TextAlignment="Center"/>
</Grid>
<Line Grid.Row="0" Fill="Black"
X2="{Binding ActualWidth, Mode=OneWay ,RelativeSource={RelativeSource Self}}"
Stroke="Black" VerticalAlignment="Bottom"/>
<ScrollViewer Grid.Row="1" MinHeight="50" VerticalScrollBarVisibility="Auto">
<ItemsPresenter/>
</ScrollViewer>
</Grid>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="col1"/>
<ColumnDefinition Width="1" SharedSizeGroup="marg"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="col2"/>
<ColumnDefinition Width="1" SharedSizeGroup="marg"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="col3"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0" VerticalAlignment="Center" Margin="3" SelectedItem="{Binding Field}"/>
<Line Grid.Column="1"
Y2="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Self}}"
Stroke="Gray"
HorizontalAlignment="Center"/>
<ComboBox Grid.Column="2" VerticalAlignment="Center" Margin="3" SelectedItem="{Binding Condition}"/>
<Line Grid.Column="3"
Y2="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Self}}"
Stroke="Gray"
HorizontalAlignment="Center"/>
<TextBox Grid.Column="4" VerticalAlignment="Center"
HorizontalAlignment="Left" Margin="3"
MinWidth="50"
Text="{Binding Value, UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True}"/>
<Line VerticalAlignment="Bottom"
Grid.ColumnSpan="6" Grid.Column="0"
X2="{Binding ActualWidth, Mode=OneWay, RelativeSource={RelativeSource Self}}"
Stroke="Black"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Grid.Column="2" Margin="0,0,20,0">
<Button Height="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" Margin="2" Padding="0"
Command="{Binding AddFilterCommand}">
<Path Stroke="Black" StrokeThickness="1" VerticalAlignment="Center">
<Path.Data>M0,5 H10 M5,0 V10</Path.Data>
</Path>
</Button>
<Button Height="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" Margin="2"
Command="{Binding RemoveFilterCommand}">
<Path Stroke="Black" StrokeThickness="1" VerticalAlignment="Center">
<Path.Data>M0,0 H8</Path.Data>
</Path>
</Button>
</StackPanel>
</Grid>
The visibility of this part is controled by my viewmodel. Until this everything is working nice, but when I add new rows to the array with the + button, I would like the array not to grow but use a ScrollViewer. So in the ItemControl.template is added the scrollViewer.
But I got this result :
How can I get the scrollviewer to work ?
Set the Height of the second RowDefinition to *:
<RowDefinition Height="*"/>
Or set the Height property of the ItemsControl or ScrollViewer.
A ScrollViewer must have a constrained height to be able to calculate the scrollable view port.

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>

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>

Content control contents sizing to fill in Silverlight 4

I have a style for a ContentControl which I want to use in places where I currently have a Border. When I use this, the child controls will not stretch to fill and only take a small amount of space. I've tried applying HorizontalAlignment="Stretch" to everything, but it doesn't work. What's wrong?
<Style x:Key="GradientPanel" TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Rectangle RadiusY="10" RadiusX="10" Stroke="Black" StrokeThickness="0">
<Rectangle.Effect>
<DropShadowEffect Opacity="0.56" ShadowDepth="1" BlurRadius="3" />
</Rectangle.Effect>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFE1EAF3"/>
<GradientStop Color="White" Offset="1"/>
<GradientStop Color="#FFFAFBFD" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
...
Before (works fine):
<Border Style="{StaticResource SearchContainerBorder}" >
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ToggleButton Style="{StaticResource ToggleButtonExpanderStyle}" Grid.Row="0" Grid.Column="1" Height="25" Width ="25" HorizontalAlignment="Center" VerticalAlignment="Top" />
<ContentControl Grid.Row="0" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
</Border>
After (replace Border with ContentControl):
<ContentControl Style="{StaticResource GradPanel}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ToggleButton Style="{StaticResource ToggleButtonExpanderStyle}" Grid.Row="0" Grid.Column="1" Height="25" Width ="25" HorizontalAlignment="Center" VerticalAlignment="Top" />
<ContentControl Grid.Row="0" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
</ContentControl>
You need to set the HorizontalContentAlignment="Stretch" and the VerticalContentAlignment="Stretch" settings on your outer ContentControl.
The default behaviour is to NOT stretch the contents of a container.
e.g. the first line should be:
<ContentControl Style="{StaticResource GradPanel}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch" >

Resources