WPF组合框绑定更新不正确 [英] WPF ComboBox Binding not updating properly

查看:203
本文介绍了WPF组合框绑定更新不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我的组合框绑定更新问题。我创建了一个简单的例子说明这个问题。我会贴上相关的所有code以下。

所以在上面的图片,我有一个TextBlock(黑色),显示SelectedPerson.FullName'为SelectedPerson属性。该SelectedPerson的名字和姓氏的属性显示在下面的全名的文本框2。组合框的DisplayMemberPath势必全名和组合框包含Person对象的列表。

在全名属性应该是在文本块,组合框,组合框和下拉列表中的相同。

然而,它仅正确TextBlock中更新。组合框下拉刚刚更新第一次被打开,之后不更新。所以,如果我在文本框中编辑名字,然后点击下拉,然后编辑它多一些,然后再次单击下拉,我们最终显示为SelectedPerson 3个不同的全名值。

我在我的code。使用INotifyPropertyChanged的后面时,SelectedPerson变更通知。这似乎做工精细更新TextBlock的,但由于某些原因,组合框不与新的全名更新。

我试图发送一个全名通知时,我发送SelectedPerson通知,但它并不能使它工作的。

任何人可以告诉我为什么组合框没有更新的时候我改名字文本?

感谢。

MainWindow.xaml:

 <窗​​口x:类=ComboBoxBinding.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
        的DataContext ={绑定的RelativeSource = {自我的RelativeSource}}>
    < StackPanel的保证金=50WIDTH =150>
        < TextBlock的保证金=0,0,0,10HEIGHT =30填充=8的背景=黑前景=白文本={结合SelectedPerson.FullName}/>
        <文本框的文本={结合SelectedPerson.FirstName,UpdateSourceTrigger =的PropertyChanged}/>
        <文本框的文本={结合SelectedPerson.LastName,UpdateSourceTrigger =的PropertyChanged}/>
        <组合框保证金=0,16,0,0
                  的ItemsSource ={结合人民}
                  的DisplayMemberPath =全名
                  的SelectedItem ={结合SelectedPerson,UpdateSourceTrigger =的PropertyChanged}>
        < /组合框>
    < / StackPanel的>
< /窗GT;

MainWindow.xaml.cs:

 使用System.Collections.Generic;
使用System.ComponentModel;命名空间ComboBoxBinding
{
    公共部分类主窗口:INotifyPropertyChanged的
    {
        公共事件PropertyChangedEventHandler的PropertyChanged;        公共无效OnPropertyChanged(字符串propertyName的)
        {
            如果(的PropertyChanged!= NULL)
            {
                的PropertyChanged(这一点,新PropertyChangedEventArgs(propertyName的));
            }
        }        私人列表<&人GT; _People =新的List<&人GT;();        公开名单<&人GT;人
        {
            {返回_People; }
        }        私募人士_selectedPerson;        公众人物SelectedPerson
        {
            {返回_selectedPerson; }
            组
            {
                _selectedPerson =价值;
                OnPropertyChanged(SelectedPerson);
            }
        }        公共主窗口()
        {
            GenerateLaneConfigurations();
            的InitializeComponent();
        }        私人无效GenerateLaneConfigurations()
        {
            People.Add(新的Person(埃尔默,Fudd语));
            People.Add(新的Person(错误,兔子));
            People.Add(新的Person(唐纳德,鸭子));            的foreach(人人_People)
            {
                person.Changed + = person_Changed;
            }            SelectedPerson =人物[0];
        }        无效person_Changed()
        {
            OnPropertyChanged(SelectedPerson);
        }
    }
}

Person.cs:

 命名空间ComboBoxBinding
{
    公共类Person
    {
        私人字符串_FirstName;
        公共字符串名字
        {
            {返回_FirstName; }
            集合{_FirstName =价值;调用onChanged(); }
        }        私人字符串_lastName;
        公共字符串姓氏
        {
            {返回_lastName; }
            集合{_lastName =价值;调用onChanged(); }
        }        公共字符串全名
        {
            {返回的String.Format({0} {1},名字,姓氏);}
        }        公众人物(字符串名字,字符串的lastName)
        {
            名字=名字;
            姓氏= lastName的;
        }        公共委托无效ChangedEventHandler();
        公共事件ChangedEventHandler更改;        保护无效调用onChanged()
        {
            如果(改变!= NULL)
            {
                改变();
            }
        }
    }
}


解决方案

您需要执行通知系统在Person对象为好。话说这 SelectedPerson 改变是不够的。刚刚实施 INotifyPropertyChanged的像你已经做你的主窗口和提高的PropertyChanged 事件,而不是您的自定义更改事件,它应该工作。

I have an updating issue with Binding in my ComboBox. I have created a simplified example illustrate this problem. I will paste all the related code below.

So in the image above, I have a TextBlock (in black) that shows the 'SelectedPerson.FullName' property for the SelectedPerson. The FirstName and LastName properties of the SelectedPerson are shown in the 2 TextBoxes below the FullName. The ComboBox DisplayMemberPath is bound to 'FullName' and the combobox contains a list of Person objects.

The 'FullName' property should be the same in the TextBlock, ComboBox, and ComboBox dropdown list.

However, it is ONLY updating correctly in the TextBlock. The comboBox Dropdown just updates the first time it is opened and doesn't update after that. So if I edit the FirstName in the textbox and click the dropdown and then edit it some more and click the dropdown again, we end up with 3 different 'FullName' values being displayed for the SelectedPerson.

I am using INotifyPropertyChanged in my code behind to notify when "SelectedPerson" is changed. This appears to work fine updating the TextBlock, but for some reason, ComboBox isn't updating with the new "FullName".

I have attempted to send a "FullName" notify when I send 'SelectedPerson' notify, but it doesn't make it work either.

Can anybody tell me why the ComboBox isn't updating when I change the FirstName text?

Thanks.

MainWindow.xaml:

<Window x:Class="ComboBoxBinding.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"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <StackPanel Margin="50" Width="150">
        <TextBlock Margin="0,0,0,10" Height="30" Padding="8" Background="Black" Foreground="White" Text="{Binding SelectedPerson.FullName}"/>
        <TextBox Text="{Binding SelectedPerson.FirstName, UpdateSourceTrigger=PropertyChanged}"/>
        <TextBox Text="{Binding SelectedPerson.LastName, UpdateSourceTrigger=PropertyChanged}"/>
        <ComboBox Margin="0,16,0,0"
                  ItemsSource="{Binding People}"
                  DisplayMemberPath="FullName"
                  SelectedItem="{Binding SelectedPerson, UpdateSourceTrigger=PropertyChanged}">
        </ComboBox>
    </StackPanel>
</Window>

MainWindow.xaml.cs:

using System.Collections.Generic;
using System.ComponentModel;

namespace ComboBoxBinding
{
    public partial class MainWindow : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

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

        private List<Person> _people = new List<Person>();

        public List<Person> People 
        {
            get { return _people; }
        }

        private Person _selectedPerson;

        public Person SelectedPerson
        {
            get { return _selectedPerson; }
            set 
            {
                _selectedPerson = value;
                OnPropertyChanged("SelectedPerson");
            }
        }

        public MainWindow()
        {
            GenerateLaneConfigurations();
            InitializeComponent();
        }

        private void GenerateLaneConfigurations()
        {
            People.Add(new Person("Elmer", "Fudd"));
            People.Add(new Person("Bugs", "Bunny"));
            People.Add(new Person("Donald", "Duck"));

            foreach (Person person in _people)
            {
                person.Changed += person_Changed;
            }

            SelectedPerson = People[0];
        }

        void person_Changed()
        {
            OnPropertyChanged("SelectedPerson");
        }
    }
}

Person.cs:

namespace ComboBoxBinding
{
    public class Person
    {
        private string _firstName;
        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; OnChanged(); }
        }

        private string _lastName;
        public string LastName
        {
            get { return _lastName; }
            set { _lastName = value; OnChanged(); }
        }

        public string FullName
        {
            get { return string.Format("{0} {1}", FirstName, LastName);}
        }

        public Person(string firstName, string lastName)
        {
            FirstName = firstName;
            LastName = lastName;
        }

        public delegate void ChangedEventHandler();
        public event ChangedEventHandler Changed;

        protected void OnChanged()
        {
            if (Changed != null)
            {
                Changed();
            }
        }
    }
}

解决方案

You need to implement the notification system in your Person object as well. Saying that the SelectedPerson changed isn't good enough. Just implement INotifyPropertyChanged on Person like you already do on your MainWindow and raise the PropertyChanged event instead of your custom Changed event and it should work.

这篇关于WPF组合框绑定更新不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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