简体   繁体   中英

Converting (Dictionary<string, List<string>>) value).Values)which is a collection to array by IValueConverter to show in a listbox

my converter is as follows-

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var fields = (((Dictionary<string, List<string>>) value).Values);

        string dogCsv = string.Join("", (object[]) fields.ToArray());
        string dogCsv1 = string.Join("", dogCsv.ToArray());
        Array ab = dogCsv1.ToArray();
        return ab;
    }

my WPF binding is as follows-

<ListBox x:Name="txt"  FontSize="20" Height="Auto" Width="Auto" MinHeight="100" MinWidth="100"
          ItemsSource="{Binding Obj.StudDetail,ElementName=window, Converter={StaticResource Converter}}">
    <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <TextBlock Text="{Binding}"  Background="Gray"/>
                <ListBox   Height="Auto" FontSize="20" MinHeight="100"
                           MinWidth="100" Width="Auto"
                           ItemsSource="{Binding Obj.StudDetail, 


ElementName=window, Converter={StaticResource Converter1}}"
                               HorizontalContentAlignment="Center"/>
                        </StackPanel>
                    </DataTemplate>
        </ListBox.ItemTemplate>
         </ListBox>

i have used datatemplate to customize UI. i want the output to be the value of my dictionary. PLease help. Thanks in advance.

Below is my C# code- XAML.CS-

public partial class MainWindow : Window
{
    public Person Obj { get; set; }

    public MainWindow()
    {
        Obj = new Person();

        List<string> subjects1 = new List<string>();

        subjects1.Add("C++");
        subjects1.Add("C");
        subjects1.Add("C#");

        List<string> subjects2 = new List<string>();

        subjects2.Add("JAVA");
        subjects2.Add("JS");
        subjects2.Add("CSS");

        Obj.StudDetail.Add("Kushagra", subjects1);
        Obj.StudDetail.Add("Yash", subjects2);

        DataContext = this;
    }

    public class Person
    {
        private Dictionary<string, List<string>> _studDetail = new Dictionary<string, List<string>>();

        public Dictionary<string, List<string>> StudDetail
        {
            get { return _studDetail; }
            set { _studDetail = value; }
        }
    }
}

} i also have one more converter class which returns the collection of keys. It is named as ValueConverter.

You don't even need the converter and you can show the data like this

<ListBox x:Name="txt"  FontSize="20" Height="Auto" Width="Auto" MinHeight="100" MinWidth="100"
                 ItemsSource="{Binding Obj.StudDetail,ElementName=window}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <TextBlock Text="{Binding Path=Key}"  Background="Gray"/>
                        <ListBox   Height="Auto" FontSize="20" MinHeight="100"
                                   MinWidth="100" Width="Auto" ItemsSource="{Binding Path=Value}"
                                   HorizontalContentAlignment="Center"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

What I did here is binding TextBlock to Key and the nested listbox to Value

While you do not actually need to use a value converter (as shown in the other answer), it may just look like shown below - with whatever separator strings you may want to use instead of blanks.

Note that the converter does not convert the whole Dictionary, but only its individual KeyValuePair entries, which are passed by {Binding Converter={StaticResource Converter} in the ListBox's ItemTemplate.

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    var result = "";

    if (value is KeyValuePair<string, List<string>>)
    {
        var kvp = (KeyValuePair<string, List<string>>)value;

        result = kvp.Key + " " + string.Join(" ", kvp.Value);
    }

    return result;
}

Your XAML would simply be this:

<ListBox ItemsSource="{Binding Obj.StudDetail, ElementName=window}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource Converter}}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Alternatively, bind the Key and Value properties separately, the latter Binding with a converter that converts from List<string> to string:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    var values = value as IEnumerable<string>;

    return values != null ? string.Join(" ", values) : "";
}

With this ItemTemplate:

<ListBox.ItemTemplate>
    <DataTemplate>
        <TextBlock>
            <Run Text="{Binding Key, Mode=OneWay}"/>
            <Run Text="{Binding Value, Converter={StaticResource Converter}, Mode=OneWay}"/>
        </TextBlock>
    </DataTemplate>
</ListBox.ItemTemplate>

Or this one:

<ListBox.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Key}"/>
            <TextBlock Text=" "/>
            <TextBlock Text="{Binding Value, Converter={StaticResource Converter}}"/>
        </StackPanel>
    </DataTemplate>
</ListBox.ItemTemplate>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM