Home > Mobile >  DataBinding Dictionary<string, string[]> property that's within an object
DataBinding Dictionary<string, string[]> property that's within an object

Time:09-19

I have a dictionary<string, string[]> consisting of 2 records within an object. I'm trying to bind the keys to a combobox, depending on what is selected the array value should populate a listview. I've tried a couple different things but the most I can get working is the dictionary keys to populate the combobox. When I switch values in the combobox and I run in debug mode, nothing is being passed to my SelectedItem property. Code below...

Model -

    public class Celebrity
    {
        public Dictionary<string, string[]> MyDict { get; set; }
    }

ViewModel -

    public class ViewModel : INotifyPropertyChanged
    {       
        public ViewModel()
        {
            Celeb = new Celebrity()
            {
                MyDict = new Dictionary<string, string[]>() {
                    { "Mark", new string[] { "a", "b" } },
                    { "Patti", new string[] { "c", "d" } }
                }
            };
        }

        private Celebrity _celebrity;
        public Celebrity Celeb
        {
            get => _celebrity;
            set
            {
                _celebrity = value;
                RaisePropertyChanged(nameof(Celeb));
            }
        }

        private Celebrity _selectedItem;
        public Celebrity SelectedItem
        {
            get => _selectedItem;
            set
            {
                _selectedItem = value;
                RaisePropertyChanged(nameof(SelectedItem));
            }
        }

/* MAYBE THIS COMMENTED OUT CODE RATHER THAN public Celebrity SelectedItem???? */

        //private KeyValuePair<string, string[]> _selectedItem;
        //public KeyValuePair<string, string[]> SelectedItem
        //{
        //    get => _selectedItem;
        //    set
        //    {
        //        _selectedItem = value;
        //        RaisePropertyChanged(nameof(SelectedItem));
        //    }
        //}

        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new
                    PropertyChangedEventArgs(propertyName));
            }
        }
    }

XAML -

                <ComboBox Width="100" Height="20" HorizontalAlignment="Left"
                    ItemsSource="{Binding Celeb.MyDict}"
                    DisplayMemberPath="Key"
                    SelectedItem="{Binding SelectedItem.MyDict}" />

                <StackPanel>
                    <ListBox 
                        ItemsSource="{Binding SelectedItem.MyDict.Values}"
                        Height="40">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <Border BorderBrush="Black" BorderThickness="2">
                                    <StackPanel>
                                        <TextBlock Text="{Binding RelativeSource= 
            {RelativeSource AncestorType=ListViewItem}}"/>
                                    </StackPanel>
                                </Border>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </StackPanel>

CodePudding user response:

I think using the commented out SelectedItem will be better..

private KeyValuePair<string, string[]> _selectedItem;
public KeyValuePair<string, string[]> SelectedItem
{
    get => _selectedItem;
    set
    {
        _selectedItem = value;
        RaisePropertyChanged(nameof(SelectedItem));
    }
}

The .xaml code would be like this

<ComboBox
    Width="100"
    HorizontalAlignment="Left"
    DisplayMemberPath="Key"
    ItemsSource="{Binding Celeb.MyDict}"
    SelectedItem="{Binding SelectedItem}" />

<StackPanel>
    <ListBox
        Height="60"
        ItemsSource="{Binding SelectedItem.Value}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border BorderBrush="Black" BorderThickness="2">
                    <StackPanel>
                        <TextBlock Text="{Binding}" />
                    </StackPanel>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</StackPanel>

So the SelectedItem of Combobox is KeyValuePair, and the ItemsSource of the ListBox is the Value (i.e. string array) of that KeyValuePair.

The TextBlock inside ListBox.ItemTemplate will be bound to the string value of the string array, so you could just use {Binding} to show the row's value.

  • Related