简体   繁体   中英

WPF C# representing List of enums as ListBox and binding the value to combobox doesn't work two way

I have set a ListBox.ItemsSource to an ObservableCollection of custom class and the DataTemplate represents the data as ComboBoxes. When the ObservableCollection gets an item added, a new ComboBox gets created inside the ListBox, and if I change a value inside the ObservableCollection the connected ComboBox gets its value updated. However, if I change the ComboBoxes' values nothing happens inside the ObservableCollection. I have set the value binding of the ComboBox to

SelectedItem="{Binding Path=., Mode=TwoWay}"

So in short, I'm trying to connect ComboBoxes to a value inside a list, so that when I change the ComboBox.SelectedItem, the right value is changed inside the list and vice versa. The problem is that the values inside the list don't get updated when the ComboBox.SelectedItem gets changed.


xaml:

<ListBox x:Name="ContainerList" Margin="5,0,5,0" Width="140">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <ComboBox 
                            ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}},Path=TestEnums}"
                            SelectedItem="{Binding Path=., Mode=TwoWay}"
                            >
                        </ComboBox>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <Button x:Name="MoreButton" Content="More" Click="AddContainerClass_Click"/>

Code behind:

 public partial class MainWindow : Window
{
    public enum TestEnum
    {
        value0,
        value1,
        value2,
        value3,
        value4,
    }

    public class ContainerClass
    {
        public ObservableCollection<TestEnum> Enums { get; set; }
        public ContainerClass()
        {
            Enums = new ObservableCollection<TestEnum>();
        }
    }

    public IEnumerable TestEnums { get; set; }
    public ContainerClass Container { get; set; }


    public MainWindow()
    {
        TestEnums = Enum.GetValues(typeof(TestEnum)).Cast<TestEnum>();
        InitializeComponent();
        Container = new ContainerClass();
        ContainerList.ItemsSource = Container.Enums;
        MoreButton.DataContext = Container;
    }

    private void AddContainerClass_Click(object sender, RoutedEventArgs e)
    {
        Button b = sender as Button;
        ContainerClass cc = b.DataContext as ContainerClass;
        cc.Enums.Add(TestEnum.value0);
    }
}

As far as I can tell you are binding to a list of enums (which happens to be in an observable collections), ok.

When an enum is added one sees it on the screen because the binding to the observable collection is smart enough subscribe to the change notification from the observable collection.

But it seems you want the enum in the list to change to a different enum via direct combobox binding; that is not possible because the observable collection is not being considered.

Why?

In a sense you are indirectly asking the observable collection to delete the item, then add a new item in its place and then send a messages about each of the changes. That is not possible with just a binding to the reference of the selected item of the list.

What to do?

It would be better to simply use the list box, remove that DataTemplate you have and create buttons below it Add , Delete and Replace , possibly with a side drop down combobox as a selection of the enums. then wire up the buttons in the code behind to work with the observable collection directly by removing the selected and replacing it if necessary.

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