可观测集合未触发setter或更新C#wpf

可观测集合未触发setter或更新C#wpf,c#,wpf,C#,Wpf,我不完全确定为什么这没有更新。因此,在我的应用程序中,您可以使用文本框修改右侧的用户名。这些变化实时反映在左侧。当您单击“添加新许可证”按钮时,它将创建新许可证并将其添加到所选客户。但是,listview列“Lincenes”似乎没有更新以反映客户拥有的许可证数量。作为测试,我在我的Obs集合中放置了一个打印语句 private ObservableCollection<License> licenses; public ObservableColle

我不完全确定为什么这没有更新。因此,在我的应用程序中,您可以使用文本框修改右侧的用户名。这些变化实时反映在左侧。当您单击“添加新许可证”按钮时,它将创建新许可证并将其添加到所选客户。但是,listview列“Lincenes”似乎没有更新以反映客户拥有的许可证数量。作为测试,我在我的Obs集合中放置了一个打印语句

        private ObservableCollection<License> licenses;
        public ObservableCollection<License> Licenses
        {
            get { return licenses ?? (licenses = new ObservableCollection<License>()); }
            set
            {
                Console.Write("Modified");
                Set(ref licenses, value);
                RaisePropertyChanged(nameof(LicensesCount));
            }
        }
私人可观测采集许可证;
公开收集许可证
{
获取{返回许可证???(许可证=新的ObservableCollection();}
设置
{
控制台。写入(“修改”);
设置(参考许可证,值);
RaiseProperty变更(名称(许可证持有人));
}
}
然而,我注意到,由于某种原因,它从未被打印出来。我对该做什么或改变感到困惑。下面是我代码的主要部分。客户和许可证类对象都是基类INotify

Customer.cs和License.cs类

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Input;
using WpfApplication1.Helper;

namespace WpfApplication1.Model
{
    public class Customer : NotifyBase
    {
        private string firstName;
        public string FirstName
        {
            get { return firstName; }
            set { Set(ref firstName, value); }
        }

        public string LicensesCount
        {
            get { return this.Licenses.Count.ToString(); }
        }

        private ObservableCollection<License> licenses;
        public ObservableCollection<License> Licenses
        {
            get { return licenses ?? (licenses = new ObservableCollection<License>()); }
            set
            {
                Console.Write("Modified");
                Set(ref licenses, value);
                RaisePropertyChanged(nameof(LicensesCount));
            }
        }

        public Customer(string firstname, string lastname, string email, string company)
        {
            this.FirstName = firstname;
        }

        // Commands
        private ICommand addNewLicense_Command;
        public ICommand AddNewLicense_Command
        {
            get { return addNewLicense_Command ?? (addNewLicense_Command = new RelayCommand<Customer>(n =>{ AddNewLicense_Execute(n); }));}
        }

        public void AddNewLicense_Execute(Customer customer)
        {
            Licenses.Add(new License("Paint"));
        }
    }


    public class License : NotifyBase
    {
        private string product;
        public string Product
        {
            get { return product; }
            set { Set(ref product, value); }
        }

        public License(string product)
        {
            this.Product = product;
        }

    }

}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;


namespace WpfApplication1.Helper
{
    public abstract class NotifyBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        protected bool Set<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) return false;
            field = value;
            RaisePropertyChanged(propertyName);
            return true;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.Security.Cryptography;
使用系统文本;
使用System.Windows.Input;
使用WpfApplication1.Helper;
命名空间WpfApplication1.Model
{
公共类客户:NotifyBase
{
私有字符串名;
公共字符串名
{
获取{return firstName;}
集合{set(ref firstName,value);}
}
公共字符串许可证
{
获取{返回this.Licenses.Count.ToString();}
}
私人收集许可证;
公开收集许可证
{
获取{返回许可证???(许可证=新的ObservableCollection();}
设置
{
控制台。写入(“修改”);
设置(参考许可证,值);
RaiseProperty变更(名称(许可证持有人));
}
}
公共客户(string firstname、string lastname、string email、string company)
{
this.FirstName=FirstName;
}
//命令
私有ICommand addNewLicense_命令;
public ICommand AddNewLicense\u命令
{
获取{return addNewLicense_Command??(addNewLicense_Command=newrelaycommand(n=>{addNewLicense_Execute(n);}));}
}
public void AddNewLicense_Execute(客户)
{
许可证。添加(新许可证(“油漆”);
}
}
公共类许可证:NotifyBase
{
私有字符串产品;
公共字符串产品
{
获取{返回产品;}
集合{set(ref乘积,值);}
}
公共许可证(字符串产品)
{
这个。产品=产品;
}
}
}
NotifyBase.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Input;
using WpfApplication1.Helper;

namespace WpfApplication1.Model
{
    public class Customer : NotifyBase
    {
        private string firstName;
        public string FirstName
        {
            get { return firstName; }
            set { Set(ref firstName, value); }
        }

        public string LicensesCount
        {
            get { return this.Licenses.Count.ToString(); }
        }

        private ObservableCollection<License> licenses;
        public ObservableCollection<License> Licenses
        {
            get { return licenses ?? (licenses = new ObservableCollection<License>()); }
            set
            {
                Console.Write("Modified");
                Set(ref licenses, value);
                RaisePropertyChanged(nameof(LicensesCount));
            }
        }

        public Customer(string firstname, string lastname, string email, string company)
        {
            this.FirstName = firstname;
        }

        // Commands
        private ICommand addNewLicense_Command;
        public ICommand AddNewLicense_Command
        {
            get { return addNewLicense_Command ?? (addNewLicense_Command = new RelayCommand<Customer>(n =>{ AddNewLicense_Execute(n); }));}
        }

        public void AddNewLicense_Execute(Customer customer)
        {
            Licenses.Add(new License("Paint"));
        }
    }


    public class License : NotifyBase
    {
        private string product;
        public string Product
        {
            get { return product; }
            set { Set(ref product, value); }
        }

        public License(string product)
        {
            this.Product = product;
        }

    }

}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;


namespace WpfApplication1.Helper
{
    public abstract class NotifyBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        protected bool Set<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) return false;
            field = value;
            RaisePropertyChanged(propertyName);
            return true;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用System.Runtime.CompilerServices;
命名空间WpfApplication1.Helper
{
公共抽象类NotifyBase:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的void RaisePropertyChanged([CallerMemberName]字符串propertyName=null)
{
if(this.PropertyChanged!=null)
this.PropertyChanged(this,newpropertychangedventargs(propertyName));
}
受保护的布尔集合(参考T字段,T值,[CallerMemberName]字符串propertyName=null)
{
if(EqualityComparer.Default.Equals(字段,值))返回false;
字段=值;
RaisePropertyChanged(propertyName);
返回true;
}
}
}

这里有一个指向解决方案的链接:

从您的代码中,当您将新的
observeCollection
设置为
Licenses
属性时,您正在更新
LicensesCount
。添加新的
许可证
对象时,
许可证
属性不变。要正确更新
licenseCont
,您应该收听
CollectionChanged
您的
许可证的事件

它应该与此类似:

private ObservableCollection<License> licenses;
public ObservableCollection<License> Licenses
{
    get { return licenses ?? (licenses = CreateLicensesCollection()); }
    set
    {
        Console.Write("Modified");
        Set(ref licenses, value);
        RaisePropertyChanged(nameof(LicensesCount));
    }
}

private ObservableCollection<License> CreateLicensesCollection()
{
    var collection = new ObservableCollection<License>();
    collection.CollectionChanged += (s, a) => RaisePropertyChanged(nameof(LicensesCount));
    return collection;
}
私人可观测采集许可证;
公开收集许可证
{
获取{返回许可证???(许可证=CreateLicensesCollection());}
设置
{
控制台。写入(“修改”);
设置(参考许可证,值);
RaiseProperty变更(名称(许可证持有人));
}
}
私有ObservableCollection CreateLicensesCollection()
{
var collection=新的ObservableCollection();
collection.CollectionChanged+=(s,a)=>RaisePropertyChanged(名称(许可证持有人));
回收;
}

为什么不直接绑定到ObservableCollection的
Count
属性?将xaml中的绑定源从
LicensesCount
更改为
Licenses.Count
。由于ObservableCollection具有INotifyPropertyChanged的内置功能,因此不需要额外的编码。

我明白了,这就解决了问题。谢谢你的帮助。有没有办法将其添加到ObservieObjectEx类中?所以它适用于任何可观察物体的类别。这样做似乎更安全。可以理解。谢谢你的帮助!你答对了