Search code examples
c#wpfxamluser-controlsuielement

How to make a UIElement width relative to the parent container (in this case, StackPanel)?


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.


Solution

  • 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);