0

How to make a UIElement (in my case it's a Line) width relative to the parent container (in this case, StackPanel)? Relative means stretched and shrink based on the parent.

<UserControl x:Class="RevisiConverter.NumericNote"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" Background="White">
<StackPanel Name="mainStack">
    <StackPanel Name="topStack">
        <Line X1="0" Y1="0" X2="20" Y2="0" Margin="0,2,0,2" Stroke="Black"/>
        <Line X1="0" Y1="0" X2="20" Y2="0" Margin="0,2,0,2" Stroke="Black"/>
    </StackPanel>
    <TextBlock Name="txbNote" Text="b5" Foreground="Black" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="15"/>
    <StackPanel Name="botStack">

    </StackPanel>
</StackPanel>
</UserControl>

In above sample, topStack is already filled by 2x Line directly from the xaml, but, in reality, it's filled from the C# code (initial Children count of topStack is 0).

The size of the UserControl is relative to its Children, but will always have at least 1 children, which is txbNote, and txbNote will always at least have 1 character.

So, in short, I need the Line length, if exists, is always equal to txbNote width. While txbNote can be updated anytime.

How to achieve this, especially from the C# code-wise?

Thank you.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Moses Aprico
  • 1,951
  • 5
  • 30
  • 53

3 Answers3

1

It is important that you realise that in WPF, different container controls behave differently. There are Panel controls, such as a Grid, that can perform resizing actions on their children controls automatically and there are other Panel controls, such as a StackPanel that don't. It is a better idea to use the correct control for the job, rather than trying to make the wrong control do a job that it was never meant to do.

In your case, I'd suggest that you replace your StackPanels with a Grids and let them automatically fill the space for you. Please see the Grid class page on MSDN for further information on this. You can also find out more about the various Panels used in WPF in the Panels Overview page on MSDN.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Using `Grid` is not possible, since `Line` can be added anytime by the user. `Grid` is nice when the number of the element can't be changed. Am I right? Not quite sure though. – Moses Aprico Jun 10 '14 at 10:48
  • *`Line` can be added anytime by the user* is *not* a reason to not use a `Grid`... they can be added to a `Grid` in exactly the same way as a `StackPanel`, but suit yourself. – Sheridan Jun 10 '14 at 10:51
  • 1
    @Moses You might then also replace the Line by a Rectangle with `Height="1"` and `HorizontalAlignment="Stretch"` which would automatically stretch to the parent width. – Clemens Jun 10 '14 at 11:36
  • @Clemens that's a great idea too! – Moses Aprico Jun 10 '14 at 19:12
0

Bind X2 to the ActualWidth of the TextBlock:

<Line ... X2="{Binding ActualWidth, ElementName=txbNote}" />
Clemens
  • 123,504
  • 12
  • 155
  • 268
0

And the code-behind binding looks like that:

var newLine = new Line();

// some newLine initializing

Binding binding = new Binding();
binding.Source = topStack;
binding.Path = new System.Windows.PropertyPath("ActualWidth");
newLine.SetBinding(Line.X2Property, binding);

topStack.Children.Add(newLine);
Alex Skiba
  • 437
  • 2
  • 15