问题描述
查看模型:
Public Class viewmodel{
//a collection of all Hardware Tests.
public observableCollection<HWTest> AllHWTests;
//constructors
viewmodel{
//here I want to subscribe to Ispassed changes.
}
}
硬件测试:
public class HWTest{
//a Collection of all Hardware types,each element have a isPassed property
//of type bool.
observableCollection<HWInterface> AllSignals;
}
硬件接口:
public Class HWInterface{
//the property I would like to subscribe to at the view model
public bool isPassed;
}
我如何订阅 isPassed?
提前致谢。
解决方法
ObservableCollection<T>
只让你观察集合成员的变化。您需要使用它来附加到每个类成员实现的事件,以查看集合成员中的各个属性何时发生变化。
以下是如何使用 (1) ObservableCollection<T>
和 (2) IObservable<T>
来完成您的要求。
首先我们需要设置我们想要观察的类:
public class HWInterface : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public HWInterface(string name)
{
this.Name = name;
}
public string Name { get; private set; }
private bool _isPassed = false;
public bool IsPassed
{
get => _isPassed;
set
{
if (_isPassed != value)
{
_isPassed = value;
this.PropertyChanged?.Invoke(this,new PropertyChangedEventArgs("IsPassed"));
}
}
}
}
请注意,我已将您的大小写更改为使用普通的 C# 惯用形式。
现在我需要一个 ObservableCollection<HWInterface>
来使用:
var oc = new ObservableCollection<HWInterface>();
对于 (1) 我需要此代码来观看集合中的项目:
PropertyChangedEventHandler pceh = (s,e) => Console.WriteLine($"1: {(s as HWInterface).Name} \"{e.PropertyName}\" changed to {(s as HWInterface).IsPassed}.");
oc.CollectionChanged += (s,e) =>
{
if (e.NewItems != null) foreach (var f in e.NewItems.OfType<HWInterface>()) f.PropertyChanged += pceh;
if (e.OldItems != null) foreach (var f in e.OldItems.OfType<HWInterface>()) f.PropertyChanged -= pceh;
};
对于 (2) 我需要此代码来观看集合中的项目:
var query =
Observable
.FromEventPattern<NotifyCollectionChangedEventHandler,NotifyCollectionChangedEventArgs>(
h => oc.CollectionChanged += h,h => oc.CollectionChanged -= h)
.Select(x =>
oc
.ToObservable()
.SelectMany(f =>
Observable
.FromEventPattern<PropertyChangedEventHandler,PropertyChangedEventArgs>(
h => f.PropertyChanged += h,h => f.PropertyChanged -= h)
.Select(y => new { foo = f,property = y.EventArgs.PropertyName })))
.Switch();
IDisposable subscription =
query
.Subscribe(x => Console.WriteLine($"2: {x.foo.Name} \"{x.property}\" changed to {x.foo.IsPassed}."));
现在我可以运行一些测试代码了:
var a = new HWInterface("A");
var b = new HWInterface("B");
var c = new HWInterface("C");
oc.Add(a);
oc.Add(b);
oc.Add(c);
b.IsPassed = true;
b.IsPassed = false;
oc.Remove(b);
b.IsPassed = true; // `b` has been removed so doesn't fire anymore
c.IsPassed = true;
这是我的输出:
1: B "IsPassed" changed to True.
2: B "IsPassed" changed to True.
1: B "IsPassed" changed to False.
2: B "IsPassed" changed to False.
1: C "IsPassed" changed to True.
2: C "IsPassed" changed to True.
,
开箱即用 ObservableCollection
没有为您提供您想要的。顾名思义,您可以观察列表内部的事物(列表中元素的 INotifyPropertyChangedEvent)。
通常,我们想知道给定 INotifyCollectionChanged
的 INotifyPropertyChanged
和 ObservableCollection
,这需要一些手动设置。我写了一篇关于这个主题的blog。
TLDR
您要使用的是DynamicData。它将允许您从列表的内部元素获取属性更改通知。