0

I have column in DataGrid to display a text message. Unfortunately it is too long. So I custom the cell column template in a textblock use TextWrapping = "Wrap"

It displays multiple lines. I don't want it. I just want to display the first two lines, at the end adding an ellipsis(...)

Is there a way to do that?

SamTh3D3v
  • 9,854
  • 3
  • 31
  • 47
Bigeyes
  • 1,508
  • 2
  • 23
  • 42

1 Answers1

1

To achieve that you need to define a custom Behavior, first make sure to add the System.Windows.Interactivity namespace ( which is part of Expression.Blend.Sdk, use NuGet to install it: Install-Package Expression.Blend.Sdk), here a basic implementation (credit goes to @Itzalive):

public class NumLinesBehaviour : Behavior<TextBlock>
    {
        public static readonly DependencyProperty MaxLinesProperty =
            DependencyProperty.RegisterAttached(
                "MaxLines",
                typeof(int),
                typeof(NumLinesBehaviour),
                new PropertyMetadata(default(int), OnMaxLinesPropertyChangedCallback));

        public static void SetMaxLines(DependencyObject element, int value)
        {
            element.SetValue(MaxLinesProperty, value);
        }

        public static int GetMaxLines(DependencyObject element)
        {
            return (int)element.GetValue(MaxLinesProperty);
        }

        private static void OnMaxLinesPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is TextBlock element) element.MaxHeight = GetLineHeight(element) * GetMaxLines(element);
        }

        public static readonly DependencyProperty MinLinesProperty =
            DependencyProperty.RegisterAttached(
                "MinLines",
                typeof(int),
                typeof(NumLinesBehaviour),
                new PropertyMetadata(default(int), OnMinLinesPropertyChangedCallback));

        public static void SetMinLines(DependencyObject element, int value)
        {
            element.SetValue(MinLinesProperty, value);
        }

        public static int GetMinLines(DependencyObject element)
        {
            return (int)element.GetValue(MinLinesProperty);
        }

        private static void OnMinLinesPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is TextBlock element) element.MinHeight = GetLineHeight(element) * GetMinLines(element);
        }

        private static double GetLineHeight(TextBlock textBlock)
        {
            double lineHeight = textBlock.LineHeight;
            if (double.IsNaN(lineHeight))
                lineHeight = Math.Ceiling(textBlock.FontSize * textBlock.FontFamily.LineSpacing);
            return lineHeight;
        }
    }

Now let's say you have a DataGrid Bound to an ObservableCollection of TestClass with the "Name" property, a basic use of the NumLinesBehaviour Behavior is as follow:

<Window ...   
    xmlns:local="clr-namespace:YourNameSpace"       
    Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
    <DataTemplate x:Key="CellTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBlock 
                Width="200"
                TextWrapping="Wrap" 
                local:NumLinesBehaviour.MaxLines="2"
                TextTrimming="WordEllipsis" 
                LineStackingStrategy="BlockLineHeight"
                Text="{Binding Name}"/>

        </StackPanel>
    </DataTemplate>
</Window.Resources>

<Grid>
    <DataGrid ItemsSource="{Binding DgCollection}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Name" CellTemplate="{StaticResource CellTemplate}" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

Make sure to set the TextTrimming of the TextBlock to "WordEllipsis".

Update

The output looks something like that:

output

SamTh3D3v
  • 9,854
  • 3
  • 31
  • 47
  • I used the solution from g t. But I got an exception. `NaN is not a valid value for property 'MaxHeight'`. – Bigeyes Feb 19 '18 at 14:50
  • I am not sure what solution you are referring to, the above behavior should work perfectly, have you changed any thing in the implementation? – SamTh3D3v Feb 19 '18 at 17:29