2
votes

I want something very simple in WPF, but I don't get it to work:

I have a grid with 2 columns: one * and one Auto. The second column contains a TextBlock. I need texttrimming to work with this TextBlock. This doesn't work currently, because the TextBlock goes outside the bounds of the grid.

Extra info:

  • The second column should be juste wide enough to contain the TextBlock. The first column should contain all remaining space. If the Grid isn't wide enough to contain the desired width of the TextBlock, the text should be trimmed.
  • The width of the Grid changes when resizing the window.
  • Nothing is static (not the text, no sizes), so hardcoded values can not be used.
  • ClipToBounds property doesn't fix this issue.
  • I can't bind MaxWidth of the TextBlock to the width of the column, otherwise the TextBlock will only getting smaller, but never bigger when resizing the window.

Code to reproduce the issue (for example in Kaxaml):

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <DockPanel>
      <Grid Height="20" Background="Blue" DockPanel.Dock="Top" Margin="100 0 100 0">
         <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto" MaxWidth="200"/>
         </Grid.ColumnDefinitions>
         <TextBlock
            Grid.Column="1"
            Background="Red"
            Text="Test tralalalalalalalalalala long string this should be trimmed!"
            TextTrimming="CharacterEllipsis"/>
      </Grid>
   </DockPanel>
</Page>

Any suggestions?

1

1 Answers

1
votes

Second solution: Use a Converter like this:

namespace StackStuff{

class WidthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if(value is Double)
        {
            return (double)value - 200; // 200 = 100+100 form the grid margin
        }

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

}

In the View, you will have:

xmlns:local="clr-namespace:StackStuff"

Then, you have to add the converter for it to be used:

 <Window.Resources>
    <local:WidthConverter x:Key="WidthConverter"/>
</Window.Resources>

And then you have to implement the converter:

<DockPanel Background="Green" x:Name="dock">
        <Grid Height="20" Background="Blue" DockPanel.Dock="Top" Margin="100 0 100 0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock MaxWidth="{Binding ActualWidth, Converter={StaticResource WidthConverter}, ElementName=dock}"
                       Grid.Column="1"

Hope this is what you wanted.