Olli
Olli

Reputation: 443

Show shortened file path in ComboBox, but full path in ComboBox dropdown

Im trying to figure out how I could display a different string in the ComboBox selection than what is displayed in the dropdown of the ComboBox.

<ComboBox SelectedItem="{Binding LocalFolderSelection, Mode=OneWayToSource}"
          ItemsSource="{Binding LocalFolders}"
          SelectedIndex="0"/>

Thats my combobox. LocalFolders contains a list of string which are basically filepaths. Due to limited UI space, I cant make the ComboBox very wide so it could display the whole string. The dropdown scales automatically to fit the whole paths which is fine, but I need to reduce the displayed selection to just the filename.

Any ideas how I could achieve this? I was hoping there would be some property which I could use to define the display text, and maybe bind it to the SelectedItem with a converter that clips off the path, but so far I havent found anything like that.

Upvotes: 2

Views: 311

Answers (1)

jhh
jhh

Reputation: 673

I believe I have what you are looking for working. Using a Converter with a custom ItemTemplate we can display the shortened path and the ContentPresenter has been modified to preserve the full path.

enter image description here

XAML:

<Window.Resources>
    <converters:ShortenFilePathConverter x:Key="ShortenFilePathConverter" />
</Window.Resources>

...

<ComboBox SelectedItem="{Binding LocalFolderSelection}" 
        ItemsSource="{Binding LocalFolders}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <Label Content="{Binding Converter={StaticResource ShortenFilePathConverter}}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
    <ComboBox.ItemContainerStyle>
        <Style TargetType="{x:Type ComboBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                        <Border x:Name="Bd"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}">
                            <StackPanel Orientation="Horizontal">
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                    <ContentPresenter.Content>
                                        <Label Content="{Binding}"/>
                                    </ContentPresenter.Content>
                                </ContentPresenter>
                            </StackPanel>
                        </Border>

                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>

Converter:

public sealed class ShortenFilePathConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return null;

        var s = value as string;

        if (s == null)
            return null;

        return Path.GetFileName(s);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

Upvotes: 1

Related Questions