Oystein
Oystein

Reputation: 1322

Replace text value on single ComboBox item using triggers

I'm using a ComboBox control to set the address integer value of a physical device. The ComboBox ItemSource is bound to a List of integers, where the first value '-1' indicates no device is connected.

I'd like the '-1' value to be shown as 'NONE'. Can this be done using triggers, so that it replaces both the text in the dropdown list and in the ComboBox itself if it has been chosen? I'm considering using enums and Description attribute, but I hoped I didn't have to go that route.

Example:

enter image description here

XAML:

<ComboBox Height="30"
          ItemsSource="{Binding Path=AddressSelection}"
          SelectedItem="{Binding Path=SelectedAddress}" />

Code:

public class MainWindowVM : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public List<int> AddressSelection
    {
        get { return new List<int>() { -1, 1, 2, 3, 4 }; }
    }

    private int _selectedAddress;
    public int SelectedAddress
    {
        get { return _selectedAddress; }
        set
        {
            SetNotify(ref _selectedAddress, value);
            Console.WriteLine("Selected address is {0}", value);
        }
    }

    public void SetNotify<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        storage = value;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Upvotes: 1

Views: 446

Answers (2)

mm8
mm8

Reputation: 169150

Short answer: Yes. You should be able to do this in pure XAML:

<ComboBox Height="30"
          ItemsSource="{Binding Path=AddressSelection}"
          SelectedItem="{Binding Path=SelectedAddress}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock>
                <TextBlock.Style>
                    <Style TargetType="TextBlock">
                        <Setter Property="Text" Value="{Binding}" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding}" Value="-1">
                                <Setter Property="Text" Value="NONE" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

Upvotes: 1

Oystein
Oystein

Reputation: 1322

Using a ValueConverter in the ComboBox ItemTemplate solved it for me.

XAML:

<Window.Resources>
    <local:ValueConverter x:Key="ValueConverter" />
</Window.Resources>
<ComboBox Height="30"
          ItemsSource="{Binding Path=AddressSelection}"
          SelectedItem="{Binding Path=SelectedAddress}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ., Converter={StaticResource ValueConverter}}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

Converter:

public class ValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if ((int)value != -1)
        {
            return ((int)value).ToString();
        }
        else
        {
            return "NONE";
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

enter image description here

Upvotes: 0

Related Questions