Search code examples
wpfxamllayouttextblockstackpanel

wpf textblock autosize/layout in stackpanel


I have the following stack panel

<StackPanel>
                <TextBlock Text="{Binding AddressLine1}" />
                <TextBlock Text="{Binding AddressLine2}" />
                <TextBlock Text="{Binding AddressLine3}"  />
                <TextBlock Text="{Binding AddressLine4}"  />
</StackPanel>

and my AddressLine2 string is null on the bound object.

My stack panel renders like

| AddressLine1 |
|              |
| AddressLine3 |
| AddressLine4 |

but I want it to render like

| AddressLine1 |
| AddressLine3 |
| AddressLine4 |

is this possible, or am I missing an obvious way to do it?

Thanks, Chris


Solution

  • Create a converter that implements IMultiValueConverter then use a MultiBinding on the text so that you only have one TextBlock with each line like this:

    class MultiStringConverter : IMultiValueConverter
    {
        public object Convert( object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture )
        {
            var text = new StringBuilder( );
            for ( int i = 0 ; i < values.Length ; i++ ) {
                string line = String.Format( "{0}", values[i] );
                if ( !String.IsNullOrEmpty( line ) ) {
                    text.AppendLine( line );
                }   // if
            }
            return text.ToString( );
        }
    
        public object[] ConvertBack( object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture )
        {
            throw new NotImplementedException( );
        }
    }
    

    And in the XAML...

        <TextBlock>
            <TextBlock.Text>
                <MultiBinding>
                    <MultiBinding.Converter>
                        <Local:MultiStringConverter />
                    </MultiBinding.Converter>
                    <Binding Path="AddressLine1" />
                    <Binding Path="AddressLine2" />
                    <Binding Path="AddressLine3" />
                    <Binding Path="AddressLine4" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>