Watarap
Watarap

Reputation: 307

IValueConverter to Name for Generic Objects or String for strings

I have a ListBox named ListBoxView which contains collection of objects. The ListBox is linked to CollectionViewSource for filtering the typed input from User.

I would like to show the Name property of the object in the ListBox when its a list of generic object, and when the ListBox contains list of strings, I would like to show them as strings. So I used IValueConverter to do this. But I am failing in using it.

Here below is the code for what I tried:

WPF

<ListBox Grid.Row="2"
         Name="BoxList"
         FontFamily="Lucida Sans"
         FontWeight="Light"
         FontSize="13"
         Margin="5"
         HorizontalContentAlignment="Left"
         VerticalContentAlignment="Center"
         SelectionChanged="BoxList_SelectionChanged"
         SelectionMode="Extended">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <ContentPresenter Content = "{Binding ElementName=BoxList,
                                          Path=ItemsSource,
                                          Converter={StaticResource PropertyValuNameConverter},
                                          ConverterParameter=Name}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Height" Value="30"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

C#

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    var name = string.Empty;
    //Check if the value is a collection and proceed
    if (value.GetType().Name == typeof(List<>).Name)
    {
        foreach (var item in (IList)value)
        {
            if (item.GetType() != typeof(string))
            {
                var prop = item.GetType().GetProperty("Name");
                var val = prop.GetValue(value, null);
                name = val.ToString();
            }
            else
                name = item.ToString();
        }

        return name;
    }

    return "Not Converted";
}

The ListBox is showing everything with the same name, in this example my list contains {a,b,c,d,e,f,j,k} but it show als as k.

enter image description here

After many attempts and many searches online I couldn't figure out where it went wrong. I am no programmer please help me understand how to solve this or where I could refer for help. Thanks

Upvotes: 0

Views: 188

Answers (1)

mm8
mm8

Reputation: 169200

Since you are iterating through all items, your converter will always return the ToString() representation of the last one.

Instead of binding to the ItemsSource, you could bind to the current item and check the type of this one:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    var currentItem = value;
    var name = "Not Converted";

    if (currentItem.GetType() != typeof(string))
    {
        var prop = currentItem.GetType().GetProperty("Name");
        var val = prop.GetValue(currentItem, null);
        name = val.ToString();
    }
    else
        name = currentItem.ToString();

    return name;
}

XAML:

<ContentPresenter Content = "{Binding Path=.,
    Converter={StaticResource PropertyValuNameConverter},
    ConverterParameter=Name}"/>

Upvotes: 1

Related Questions