Question

I have a ComboBox that shows text of various lengths. For texts that are not long there is not a problem. For the texts longer than the width of ComboBox I would like to trim the text and add "..." (an ellipsis) at the end to show them properly. The bottom line is that I don't want to change the width of the ComboBox. Does anyone know how to do this?

Was it helpful?

Solution

Use a custom ItemTemplate for your ComboBox, which makes use of a TextBlock with the TextTrimming property set to CharacterEllipsis.

Example:

<ComboBox ItemsSource="..." SelectedValuePath="...">
  <ComboBox.ItemTemplate>
    <DataTemplate>
      <TextBlock 
        Text="{Binding ...}" 
        TextTrimming="CharacterEllipsis" />
    </DataTemplate>
  </ComboBox.ItemTemplate>
</ComboBox>

OTHER TIPS

The answer, as Ross said, is to implement a custom ItemTemplate. However, to make it work properly, you need to do the binding properly.

A note on this method: You cannot set both the DisplayMemberPath and the ItemTemplate, it must be one or the other.

So, for the general case where the display member is the item (such as for a string), you can use binding with no properties to bind to the DataContext of the template:

<ComboBox ItemsSource="..." SelectedValuePath="...">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding }" TextTrimming="CharacterEllipsis" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

Or, you can put it in a style.

<Style TargetType="{x:Type ComboBox}">
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBlock Text="{Binding }" TextTrimming="CharacterEllipsis" />
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

For the case where you want to bind to a specific property of the object, similar to how you would use the DisplayMemberPath property, replace the binding with the binding that you would use to a property on the object that you are binding. So, replace the fourth line in my first example with something like this:

<TextBlock Text="{Binding MyDisplayMemberProperty}" TextTrimming="CharacterEllipsis" />

The binding is in the context of a single item of the type bound to your ComboBox. To make this more explicit, you can do the following:

<DataTemplate DataType="{x:Type namespace:MyItemType}">
    <!-- My DataTemplate stuff here -->
</DataTemplate>

This will give you hints for the properties on the object while you are writing code inside the DataTemplate.

You can use TextTrimming CharacterEllipsis or WordEllipsis for the textblocks in your combobox.

Also works with a more complex DataTemplate; however, I had to resort to a DockPanel instead of the standard WrapPanel.

<ComboBox>
  <ComboBox.ItemTemplate>
    <DataTemplate>
      <DockPanel>
        <AccessText DockPanel.Dock="Left" Text="{Binding Icon}"/>
        <TextBlock Text="{Binding Name}"  TextTrimming="CharacterEllipsis" />
      </DockPanel>
    </DataTemplate>
  </ComboBox.ItemTemplate>
</ComboBox> 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top