【问题标题】:Call a function when INotifyPropertyChanged - UWP c#INotifyPropertyChanged 时调用函数 - UWP c#
【发布时间】:2026-01-28 08:50:01
【问题描述】:

我每分钟都会调用一个函数,它将值分配给 SelectedSchoolList 的可观察集合。如果此可观察集合中的任何数据发生更改,我想调用另一个函数(例如:CallIfValueChanged();)。我怎样才能做到这一点?

我的代码:

  public static ObservableCollection<SelectedSchoolList> _SelectedSchoolList = new ObservableCollection<SelectedSchoolList>();

        DispatcherTimer dispatcherTimer;
        dispatcherTimer = new DispatcherTimer();
        dispatcherTimer.Tick += dispatcherTimer_Tick;
        dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
        dispatcherTimer.Start();

        // callback runs on UI thread
       async void  dispatcherTimer_Tick(object sender, object e)
        {
        response_from_server = await CallWebService();
        if (!response_from_server.Equals("FAIL", StringComparison.CurrentCultureIgnoreCase))
        {
        parseJSONandAssignValuesToSelectedSchoolList (response_from_server);//this function assigns values to _SelectedSchoolList  
        }                                 
        }
      CallIfValueChanged();// I want to call this function here only if any data on '_SelectedSchoolList' is updated/changed

我的班级:

  class SelectedSchoolList : INotifyPropertyChanged
{
    public string SchoolName { get; set; }
    public string Score { get; set; }
    public ObservableCollection<SelectedStudentList> SelectedStudentArray { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;
}
public class SelectedStudentList
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public string IndividualScore { get; set; }

}

【问题讨论】:

  • PropertyChanged 是一个事件。您可以像处理任何其他事件一样处理它。
  • 请定义“如果有任何数据更改”,并显示分配代码。
  • 请看我编辑的代码

标签: c# uwp observablecollection inotifypropertychanged


【解决方案1】:

首先,您在实现中需要修复一些错误。你没有正确实现INotifyPropertyChanged接口。

SchoolName 属性为例,如果您将其设置为新值,则根本不会触发PropertyChanged 事件,这意味着不会更新 UI 以反映更改。

class SelectedSchoolList : INotifyPropertyChanged
{
    public string SchoolName { get; set; }
    //... other code omitted
}

您应该在属性的 setter 中触发 PropertyChanged 事件。并对您在绑定中使用的所有属性执行此操作。

问:如果此 observable 集合中的任何数据发生更改,我想调用另一个函数(例如:CallIfValueChanged();)。

您可以向_SelectedSchoolListCollectionChanged 事件注册一个事件处理程序,该事件被触发

添加、删除、更改、移动项目或刷新整个列表时。

在事件处理程序中调用您的方法。

【讨论】:

  • 如何在我的代码下编写collectionchanged事件?我的课程和代码在两个不同的页面中。
  • My class中的代码不用改,在My code中加入这一行即可:_SelectedSchoolList.CollectionChanged += CallIfValueChanged;
  • 它显示:“无法将类型 void 隐式转换为 system.collections.specialised.notifycollectionchangedeventhandler”
【解决方案2】:

尝试为每个公共属性添加私有字段,NotifyPropertyChanged 方法到您的类。然后更改setter和getter。例如:

class SelectedSchoolList : INotifyPropertyChanged
{
   private string _schoolName;
   private string _score;

   public string SchoolName 
   { 
       get => _schoolName; 
       set { _schoolName = value; NotifyPropertyChanged();}
   }
   public string Score 
   { 
       get => _score; 
       set { _score = value; NotifyPropertyChanged();}
   }
   public ObservableCollection<SelectedStudentList> SelectedStudentArray{ get; set;}

   public event PropertyChangedEventHandler PropertyChanged;

   private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
   {
       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   }
 }

最后给_SelectedSchoolListCollectionChanged事件添加一个方法:

_SelectedSchoolList.CollectionChanged += (sender, e) => { CallIfValueChanged(); };

【讨论】:

  • 这个(sender,e)参数应该是什么?
  • 这是一个 lambda 表达式。阅读更多:Lambda Expression。 (sender, e) 是一个没有名称的函数,有 2 个参数:(object sender, NotifyCollectionChangedEventArgs e){ CallIfValueChanged(); } 是函数的主体,函数将返回 void
  • 你可以用如下函数替换它:private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { CallIfValueChanged(); }
  • 好的,如果我使用多个可观察集合 - 那么,我如何确定哪个可观察集合被更改了
  • 您可以通过object sender 获取它:var collection = (sender as ObserverbalCollection&lt;SelectedSchoolList&gt;);sender 是对象的属性已更改。