Search code examples
wpfdata-binding

WPF: make labels in different but similar controls have the same width


I have a UserControl like this:

<UserControl x:Class="TextEntryControl">
    <StackPanel Orientation="Horizontal">
         <TextBlock Width="{Binding MaxLabelWidth}">First Label</TextBlock>
         <TextBlock>Label Information</TextBlock>
    </StackPanel>
</UserControl>

And another like this:

<UserControl x:Class="GroupTextEntryControl">
    <StackPanel>
        <local:TextEntryControl DataContext="{Binding DC1}" />
        <local:TextEntryControl DataContext="{Binding DC2}" />
        <local:TextEntryControl DataContext="{Binding DC3}" />
    </StackPanel>
</UserControl>

I will like to let the <TextBlock Width="{Binding MaxLabelWidth}">First Label</TextBlock> in all the controls in the GroupTextEntryControl to be the same width ... the width of the longest label.

I tried defining a dependency property but I have a hard time determining the longest width to bind to all the controls ...

UPDATE: Layour of UserControls

<Border BorderBrush="{StaticResource BackgroundVeryVeryLightGrayBrush}" BorderThickness="0 0 0 1">
        <Grid Margin="10">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Name="LabelColumnDefinition" Width="Auto" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <Border  Grid.Row="0" Grid.Column="0" >
                <Image Width="15" Margin="2" Source="{Binding ImageName, Converter={x:Static local:NameToImageConverter.Instance}}" ToolTip="{Binding ToolTip}"/>
            </Border>
            <TextBlock Grid.Row="0" Grid.Column="1"  
                   Text="{Binding Label, FallbackValue=Text}"
                   x:Name="Label"
                   FontSize="{StaticResource FontSizeRegular}"
                   FontFamily="{StaticResource NunitoRegular}"
                   Padding="2"
                   ToolTip="{Binding ToolTip}"
                   VerticalAlignment="Center"
                   Width="{Binding MaxLabelWidth}"/>

            <TextBox Grid.Row="0" Grid.Column="2" 
                 ToolTip="{Binding ErrorMessage}" ToolTipService.IsEnabled="{Binding ErrorAvailable}"
                 Text="{Binding InputTextValue, UpdateSourceTrigger=PropertyChanged}"
                 Foreground="{Binding ErrorAvailable, Converter={local:BooleanToForegroundColorConverter}}"
                 FontFamily="{StaticResource NunitoRegular}"
                 FontSize="{StaticResource FontSizeSmall}" />
            <Border  Grid.Row="0" Grid.Column="3" >
                <Image Width="15" Margin="2" Source="{Binding ErrorImage, Converter={x:Static local:NameToImageConverter.Instance}}" ToolTip="{Binding ErrorMessage}" ToolTipService.IsEnabled="{Binding ErrorAvailable}" />
            </Border>
        </Grid>
    </Border>

Solution

  • Need to use Grid and Shared Size:

    <UserControl x:Class="TextEntryControl"
                 HorizontalAlignment="Left">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="TextEntryControl_First"/>
                <ColumnDefinition SharedSizeGroup="TextEntryControl_Information"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0"
                       Text="{Binding First_Label}"/>
            <TextBlock Grid.Column="1"
                       Text="{Binding Label_Information}"/>
        </Grid>
    </UserControl>
    
    <UserControl x:Class="GroupTextEntryControl">
        <StackPanel Grid.IsSharedSizeScope="True">
            <local:TextEntryControl DataContext="{Binding DC1}" />
            <local:TextEntryControl DataContext="{Binding DC2}" />
            <local:TextEntryControl DataContext="{Binding DC3}" />
        </StackPanel>
    </UserControl>
    

    Result:
    enter image description here

        public class GroupText
        {
            public TextItem DC1 { get; } = new TextItem("One", "11111");
            public TextItem DC2 { get; } = new TextItem("Eleven", "222");
            public TextItem DC3 { get; } = new TextItem("Seven", "33333333333");
        }