如果想要拥有一组值,并在该集合发生更改时通知,则可以使用ObservableCollection
及其CollectionChanged
事件。
但是,只有在修改集合本身时才触发它的CollectionChanged
事件,而不是它包含的值。例如,如果我有ObservableCollection<Image>
,我将无法检测到有人访问集合的第N个图像并调用修改它的方法。如果我有一个ObservableCollection<Color>
,那同样的事情也是如此。如果我希望能够监视列表中包含的Color结构何时被分配,则项目本身必须是可观察的(递归地)。 Color
结构不可观察,我想将其封装到名为ObservableColor
的结构中。
问题在于,编译器对我大吼大叫,因为事件没有在构造函数中初始化。首先,我不知道一个事件必须被初始化,其次我不知道它应该如何被初始化。
以下是我的代码:
struct ObservableColor : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Color Value { get; private set; }
public ObservableColor(Color color)
{
Value = color;
}
public void Set(Color color)
{
Color oldColor = Value;
Value = color;
if (Value != oldColor)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value"));
}
}
}
如何进行编译?谢谢。
答案 0 :(得分:2)
C#要求在值类型的构造函数中显式初始化所有字段。您收到此错误只是因为PropertyChanged
在构造函数完成之前未分配任何内容。解决这个问题很简单,只需这样做:
public ObservableColor(Color color)
{
Value = color;
PropertyChanged = null;
}
那就是说,你应该考虑改变你的方法。可变结构是所有类型的头痛,意外行为和微妙的错误的来源,可以让你发疯。我建议将ObservableColor
更改为引用类型。
答案 1 :(得分:0)
正如评论中已经提到的,mutable structs are evil。因此,进行此编译的最佳方法是将此类型设为class
:
class ObservableColor : INotifyPropertyChanged
{...}
如果您确实需要这是struct
,那么您的构造函数必须初始化struct
的所有字段,甚至是event
:
struct ObservableColor : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Color Value { get; private set; }
public ObservableColor(Color color)
{
Value = color;
PropertyChanged = null; // initiailze
}