Search code examples
wpfcheckboxgridresizabletexttrimming

WPF: TextTrimming in CheckBox with no fixed width


I have a checkbox located in a grid with a column span of 3, where 2 of the columns are resizable, and can be resized during runtime.

I want the checkbox to show ellipsis when its text doesn't fit, but can't get this to work.

Here is my XAML code.

<Grid>
     <Grid.ColumnDefinitions>
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="Auto" />
     </Grid.ColumnDefinitions>
...
    <CheckBox IsEnabled="False"  Grid.Row="2" Padding="5" Margin="11,12,0,0" Name="chkSelectedCat" VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.ColumnSpan="3">
         <AccessText Text="Search in selected category only." TextTrimming="CharacterEllipsis"/>
    </CheckBox>

Thanks in advance for your help.

EDIT

The CheckBox in question is located within a Grid, which is in turn contained within a GroupBox, which is in a column adjacent to a column which is resized using a GridSplitter.


Solution

  • The problem was that the GroupBox allots infinite width to its child controls, as discussed at this MSDN forum thread.

    In fact, when setting a MaxWidth to the CheckBox, text trimming worked and the ellipsis were displayed.

    However the CheckBox maximum width needed to be changed during runtime.

    I tried using a MultiValueConverter to bind the MaxWidth of the CheckBox to the total ActualWidth of the three columns, but the Convert method was only being called during initialisation (again I think this is something to do with how the GroupBox assigns sizes to its child controls).

    Anyway I managed to achieve what I wanted by removing the ChechkBox's AccessText and using a TextBlock in a StackPanel in its stead, and then surrounding everything with a Border.

    <Border Grid.Row="2" Grid.ColumnSpan="3" Name="chkBorder" SizeChanged="chkBorder_SizeChanged">
         <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch">
                   <CheckBox IsEnabled="False" Padding="0" Margin="11,7,0,5" Name="chkSelectedCat"  VerticalAlignment="Center"/>
                   <TextBlock Foreground="Black" Name="txtChkSelectedCat" Text="Search in selected category only." TextTrimming="CharacterEllipsis" TextWrapping="NoWrap" VerticalAlignment="Center" Margin="0,5,5,5"/>
          </StackPanel>
    </Border>
    

    When the size of the Border is changed, I update the Width of the StackPanel in the event handler, and the text in the TextBox trims accordingly.

    private void chkBorder_SizeChanged(object sender, SizeChangedEventArgs e)
    {
         this.txtChkSelectedCat.Width = this.chkBorder.ActualWidth - this.chkSelectedCat.ActualWidth - 11 - 5 - 5; // margins
    }
    

    Hope this helps someone in the future (even though it is sort of a hack).

    UPDATE

    If you can eliminate the StackPanel and use a Grid instead, TextTrimming works automatically, without having to do any event handling, as shown below.

    <Grid Grid.Row="2" Grid.ColumnSpan="3">
         <Grid.ColumnDefinitions>
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="*" />
         </Grid.ColumnDefinitions>
         <CheckBox Grid.Column="0" IsEnabled="False" Padding="0" Margin="11,7,0,5" Name="chkSelectedCat" VerticalAlignment="Center" ToolTipService.ShowOnDisabled="True"/>
         <TextBlock Grid.Column="1" Foreground="Black"  Name="txtChkSelectedCat" Text="Search in selected category only." TextTrimming="CharacterEllipsis" TextWrapping="NoWrap" VerticalAlignment="Center" Margin="0,5,5,5" MouseLeftButtonDown="txtChkSelectedCat_MouseLeftButtonDown" ToolTip="{Binding ElementName=chkSelectedCat, Path=ToolTip}" />
    </Grid>
    

    Make sure to set the Width of the column containing the textbox to "*", because "Auto" basically tells the TextBox that it can have as much space as it wants, so TextTrimming would not work.