Why isn't my selected item's data binding updating?

我是研究僧i 提交于 2019-12-11 19:47:08

问题


The code below creates two list boxes. When an item in the first list box is selected, I am trying to select the corresponding item in the second list box when there is a match between NameOne and NameTwo. However, it does not select my item in the second list box. Why is that?

XAML:

<Window x:Class="ListBoxTesting.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ListBox Name="ListBoxOne" Grid.Row="0" ItemsSource="{Binding ListOne}" SelectedItem="{Binding SelectedTypeOne}" DisplayMemberPath="NameOne"/>
        <ListBox Name="ListBoxTwo" Grid.Row="1" ItemsSource="{Binding ListTwo}" SelectedItem="{Binding SelectedTypeTwo}" DisplayMemberPath="NameTwo"/>
    </Grid>
</Window>

Code:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public class TypeOne : INotifyPropertyChanged
    {
        public string NameOne { get; set; }

        public TypeOne(string name)
        {
            NameOne = name;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
    }

    public class TypeTwo : INotifyPropertyChanged
    {
        public string NameTwo { get; set; }

        public TypeTwo(string name)
        {
            NameTwo = name;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
    }

    TypeOne m_SelectedTypeOne;

    public TypeOne SelectedTypeOne
    {
        get
        {
            return m_SelectedTypeOne;
        }
        set
        {
            m_SelectedTypeOne = value;
            SelectedTypeOne.NotifyPropertyChanged("NameOne");
            foreach (TypeTwo typeTwo in ListTwo)
            {
                if (typeTwo.NameTwo == value.NameOne)
                {
                    SelectedTypeTwo = typeTwo;
                }
            }
        }
    }

    TypeTwo m_SelectedTypeTwo;

    public TypeTwo SelectedTypeTwo
    {
        get
        {
            return m_SelectedTypeTwo;
        }
        set
        {
            m_SelectedTypeTwo = value;
            SelectedTypeTwo.NotifyPropertyChanged("NameTwo");
        }
    }

    public List<TypeOne> ListOne { get; set; }
    public List<TypeTwo> ListTwo { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        ListOne = new List<TypeOne>();
        ListOne.Add(new TypeOne("Mike"));
        ListOne.Add(new TypeOne("Bobby"));
        ListOne.Add(new TypeOne("Joe"));
        ListTwo = new List<TypeTwo>();
        ListTwo.Add(new TypeTwo("Mike"));
        ListTwo.Add(new TypeTwo("Bobby"));
        ListTwo.Add(new TypeTwo("Joe"));
    }
}

回答1:


Create a "Container" ViewModel which implements INotifyPropertyChanged instead of using the Window itself as a container.

Doing DataContext = this; is not recommended.

public class ViewModel: INotifyPropertyChanged
{
    public TypeOne SelectedTypeOne
    {
        get { return m_SelectedTypeOne; }
        set
        {
            m_SelectedTypeOne = value;

            NotifyPropertyChanged("SelectedTypeOne");

            //foreach (TypeTwo typeTwo in ListTwo)
            //{
            //    if (typeTwo.NameTwo == value.NameOne)
            //   {
            //        SelectedTypeTwo = typeTwo;
            //    }
            //}
            //these kind of horrible for loops from 500 years ago are not needed in C#. Use proper LINQ:

            SelectedTypeTwo = ListTwo.FirstOrDefault(x => x.NameTwo == value.NameOne);
        }
    }

    TypeTwo m_SelectedTypeTwo;

    public TypeTwo SelectedTypeTwo
    {
        get { return m_SelectedTypeTwo; }
        set
        {
            m_SelectedTypeTwo = value;
            NotifyPropertyChanged("SelectedTypeTwo");
        }
    }
}

Then, in the UI:

DataContext = new ViewModel();


来源:https://stackoverflow.com/questions/22208875/why-isnt-my-selected-items-data-binding-updating

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!