How to display too long text properly in WPF ComboBox
Asked Answered
G

4

11

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?

Grani answered 11/5, 2012 at 10:30 Comment(0)
E
13

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>
Evvoia answered 11/5, 2012 at 10:38 Comment(1)
The binding that exists on the Combobox previously is not working in this formatLoehr
S
9

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.

Septuplicate answered 30/1, 2018 at 0:36 Comment(2)
This answer is excellent, Lauraducky. It can be a risk to answer old questions, in case one's work appears to go unrewarded, but nevertheless a number of the 5,917+ readers of this page will have benefited from your work. Keep it up!Loire
@Loire thank you. I certainly didn't answer out of an expectation to get lots of upvotes, hopefully this is useful to someone out there :)Septuplicate
T
0

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

Transient answered 11/5, 2012 at 10:36 Comment(0)
S
0

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> 
Seamark answered 21/2, 2021 at 19:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.