为什么我选择的项目的数据绑定更新? [英] Why isn't my selected item's data binding updating?

查看:83
本文介绍了为什么我选择的项目的数据绑定更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下code创建两个列表框。当选择在第一个列表框中的一个项目,我想选择在第二个列表框中相应的项目时,有名称一和NameTwo之间的匹配。但是,它不会在第二个列表框中选择我的项目。这是为什么?

XAML:

 <窗​​口x:类=ListBoxTesting.MainWindow
        的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
        的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
        标题=主窗口HEIGHT =350WIDTH =525>
    <网格和GT;
        < Grid.RowDefinitions>
            < RowDefinition高度=*/>
            < RowDefinition高度=*/>
        < /Grid.RowDefinitions>
        <列表框名称=ListBoxOneGrid.Row =0的ItemsSource ={结合那么listOne}的SelectedItem ={结合SelectedTypeOne}的DisplayMemberPath =名称一/>
        <列表框名称=ListBoxTwoGrid.Row =1的ItemsSource ={结合ListTwo}的SelectedItem ={结合SelectedTypeTwo}的DisplayMemberPath =NameTwo/>
    < /网格和GT;
< /窗GT;

code:

 使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.ComponentModel;
使用System.Linq的;
使用System.Text;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls的;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;命名空间ListBoxTesting
{
    ///<总结>
    ///为MainWindow.xaml交互逻辑
    ///< /总结>
    公共部分类主窗口:窗口
    {
        公共类TypeOne:INotifyPropertyChanged的
        {
            公共字符串名称一{搞定;组; }            公共TypeOne(字符串名称)
            {
                名称一=名称;
            }            公共事件PropertyChangedEventHandler的PropertyChanged;            公共无效NotifyPropertyChanged(字符串属性)
            {
                如果(的PropertyChanged!= NULL)
                {
                    的PropertyChanged(这一点,新PropertyChangedEventArgs(属性));
                }
            }
        }        公共类TypeTwo:INotifyPropertyChanged的
        {
            公共字符串NameTwo {搞定;组; }            公共TypeTwo(字符串名称)
            {
                NameTwo =名称;
            }            公共事件PropertyChangedEventHandler的PropertyChanged;            公共无效NotifyPropertyChanged(字符串属性)
            {
                如果(的PropertyChanged!= NULL)
                {
                    的PropertyChanged(这一点,新PropertyChangedEventArgs(属性));
                }
            }
        }        TypeOne m_SelectedTypeOne;        公共TypeOne SelectedTypeOne
        {
            得到
            {
                返回m_SelectedTypeOne;
            }
            组
            {
                m_SelectedTypeOne =价值;
                SelectedTypeOne.NotifyPropertyChanged(名称一);
                的foreach(TypeTwo typeTwo在ListTwo)
                {
                    如果(typeTwo.NameTwo == value.NameOne)
                    {
                        SelectedTypeTwo = typeTwo;
                    }
                }
            }
        }        TypeTwo m_SelectedTypeTwo;        公共TypeTwo SelectedTypeTwo
        {
            得到
            {
                返回m_SelectedTypeTwo;
            }
            组
            {
                m_SelectedTypeTwo =价值;
                SelectedTypeTwo.NotifyPropertyChanged(NameTwo);
            }
        }        公开名单< TypeOne>那么listOne {搞定;组; }
        公开名单< TypeTwo> ListTwo {搞定;组; }
        公共主窗口()
        {
            的InitializeComponent();
            的DataContext =这一点;
            那么listOne =新的List< TypeOne>();
            ListOne.Add(新TypeOne(迈克));
            ListOne.Add(新TypeOne(巴比));
            ListOne.Add(新TypeOne(乔));
            ListTwo =新的List< TypeTwo>();
            ListTwo.Add(新TypeTwo(迈克));
            ListTwo.Add(新TypeTwo(巴比));
            ListTwo.Add(新TypeTwo(乔));
        }
    }
}


解决方案

创建一个容器视图模型,它实现 INotifyPropertyChanged的而不是使用窗口本身作为一个容器。

的DataContext =这一点; 不建议

 公共类视图模型:INotifyPropertyChanged的
{
    公共TypeOne SelectedTypeOne
    {
        {返回m_SelectedTypeOne; }
        组
        {
            m_SelectedTypeOne =价值;            NotifyPropertyChanged(SelectedTypeOne);            //的foreach(TypeTwo typeTwo在ListTwo)
            // {
            //如果(typeTwo.NameTwo == value.NameOne)
            // {
            // SelectedTypeTwo = typeTwo;
            //}
            //}
            //不需要在C#这几样可怕的从500年前的循环。使用合适的LINQ:            SelectedTypeTwo = ListTwo.FirstOrDefault(X => x.NameTwo == value.NameOne);
        }
    }    TypeTwo m_SelectedTypeTwo;    公共TypeTwo SelectedTypeTwo
    {
        {返回m_SelectedTypeTwo; }
        组
        {
            m_SelectedTypeTwo =价值;
            NotifyPropertyChanged(SelectedTypeTwo);
        }
    }
}

然后,在用户界面:

 的DataContext =新视图模型();

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:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ListBoxTesting
{
    /// <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"));
        }
    }
}

解决方案

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();

这篇关于为什么我选择的项目的数据绑定更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆