我觉得这个话题对很多人来说都是一场真正的挣扎,所以它实际上已经很好了!然而,所提供的解决方案似乎都不适用于我。
正如标题所说,它是关于ObservableCollection在项目的值发生变化时不会触发的问题,只有当项目本身以某种方式被删除,添加或更改时才会触发。
我尝试使用BindingList解决方案 - 即使很多人不服从它 - 并且它没有用,解决方案扩展了ObservableCollections,如here所述。它似乎都没有工作......这就留下了一个问题:错误是我认为的地方还是其他地方的错误!!
好吧,我的代码是:
基类的:
public class ModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propName = "")
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
class TestSensor : ModelBase
{
private bool isOnline;
public bool IsOnline
{
get
{
return isOnline;
}
set
{
if (isOnline != value)
{
isOnline = value;
this.OnPropertyChanged();
}
}
}
private double sensorDatauStrain;
public double SensorDatauStrain
{
get { return sensorDatauStrain; }
set
{
if (sensorDatauStrain != value)
{
sensorDatauStrain = value;
this.OnPropertyChanged();
}
}
}
private double sensorDatakNewton;
public double SensorDatakNewton
{
get { return sensorDatakNewton; }
set
{
if (sensorDatakNewton != value)
{
sensorDatakNewton = value;
this.OnPropertyChanged();
}
}
}
private double sensorDataTon;
public double SensorDataTon
{
get { return sensorDataTon; }
set
{
if (sensorDataTon != value)
{
sensorDataTon = value;
this.OnPropertyChanged();
}
}
}
private double sensorDatausTon;
public double SensorDatausTon
{
get { return sensorDatausTon; }
set
{
if (sensorDatausTon != value)
{
sensorDatausTon = value;
this.OnPropertyChanged();
}
}
}
private string sensorName;
public string SensorName
{
get { return sensorName; }
set
{
if (sensorName != value)
{
sensorName = value;
this.OnPropertyChanged();
}
}
}
public TestSensor(string name, double ustrain,double kNewton, double ton, double uston)
{
this.SensorName = name;
this.SensorDatauStrain = ustrain;
this.SensorDatakNewton = kNewton;
this.SensorDataTon = ton;
this.SensorDatausTon = uston;
this.IsOnline = true;
}
}
然后我有一个包含这些传感器的类:
class Holm : ModelBase
{
public Holm(String Name, TestSensor sensor1, TestSensor sensor2)
{
Sensor1 = sensor1;
Sensor2 = sensor2;
this.Name = Name;
}
private string name;
public string Name
{
get
{
return name;
}
set
{
if (name != value)
{
name = value;
this.OnPropertyChanged();
}
}
}
private TestSensor sensor1;
public TestSensor Sensor1
{
get
{
return sensor1;
}
set
{
if (sensor1 != value)
{
sensor1 = value;
this.OnPropertyChanged();
}
}
}
private TestSensor sensor2;
public TestSensor Sensor2
{
get
{
return sensor2;
}
set
{
if (sensor2 != value)
{
sensor2 = value;
this.OnPropertyChanged();
}
}
}
public bool IsOnline
{
get
{
if (!Sensor1.IsOnline || !Sensor2.IsOnline)
{
return false;
}
else
{
return true;
}
}
}
}
最后是包含我失败的ObservableCollection的ViewModel - 排除了一些不相关的东西:
class MainViewViewModel : ModelBase
{
public ItemsChangeObservableCollection<Holm> HolmList { get;set;}
public MainViewViewModel()
{
Sensor11 = new TestSensor("Sensor 1.1", 0, 0, 0, 0);
Sensor12 = new TestSensor("Sensor 1.2", 0, 0, 0, 0);
Sensor21 = new TestSensor("Sensor 2.1", 0, 0, 0, 0);
Sensor22 = new TestSensor("Sensor 2.2", 0, 0, 0, 0);
Sensor31 = new TestSensor("Sensor 3.1", 0, 0, 0, 0);
Sensor32 = new TestSensor("Sensor 3.2", 0, 0, 0, 0);
Sensor41 = new TestSensor("Sensor 4.1", 0, 0, 0, 0);
Sensor42 = new TestSensor("Sensor 4.2", 0, 0, 0, 0);
Holm1 = new Holm("Holm 1", Sensor11, Sensor12);
Holm2 = new Holm("Holm 2", Sensor21, Sensor22);
Holm3 = new Holm("Holm 3", Sensor31, Sensor32);
Holm4 = new Holm("Holm 4", Sensor41, Sensor42);
HolmList = new ItemsChangeObservableCollection<Holm>();
HolmList.Add(Holm1);
HolmList.Add(Holm2);
HolmList.Add(Holm3);
HolmList.Add(Holm4);
}
private TestSensor sensor11;
public TestSensor Sensor11
{
get { return sensor11; }
set
{
if (sensor11 != value)
{
sensor11 = value;
this.OnPropertyChanged();
this.OnPropertyChanged("Holm1");
this.OnPropertyChanged("HolmList");
}
}
}
private TestSensor sensor12;
public TestSensor Sensor12
{
get { return sensor12; }
set
{
if (sensor12 != value)
{
sensor12 = value;
this.OnPropertyChanged();
this.OnPropertyChanged("Holm1");
this.OnPropertyChanged("HolmList");
}
}
}
private TestSensor sensor21;
public TestSensor Sensor21
{
get { return sensor21; }
set
{
if (sensor21 != value)
{
sensor21 = value;
this.OnPropertyChanged();
}
}
}
private TestSensor sensor22;
public TestSensor Sensor22
{
get { return sensor22; }
set
{
if (sensor22 != value)
{
sensor22 = value;
this.OnPropertyChanged();
}
}
}
private TestSensor sensor31;
public TestSensor Sensor31
{
get { return sensor31; }
set
{
if (sensor31 != value)
{
sensor31 = value;
this.OnPropertyChanged();
}
}
}
private TestSensor sensor32;
public TestSensor Sensor32
{
get { return sensor32; }
set
{
if (sensor32 != value)
{
sensor32 = value;
this.OnPropertyChanged();
}
}
}
private TestSensor sensor41;
public TestSensor Sensor41
{
get { return sensor41; }
set
{
if (sensor41 != value)
{
sensor41 = value;
this.OnPropertyChanged();
}
}
}
private TestSensor sensor42;
public TestSensor Sensor42
{
get { return sensor42; }
set
{
if (sensor42 != value)
{
sensor42 = value;
this.OnPropertyChanged();
}
}
}
private Holm holm1;
public Holm Holm1
{
get
{
return holm1;
}
set
{
if (holm1 != value)
{
holm1 = value;
this.OnPropertyChanged();
this.OnPropertyChanged("HolmList");
}
}
}
private Holm holm2;
public Holm Holm2
{
get
{
return holm2;
}
set
{
if (holm2 != value)
{
holm2 = value;
this.OnPropertyChanged();
}
}
}
private Holm holm3;
public Holm Holm3
{
get
{
return holm3;
}
set
{
if (holm3 != value)
{
holm3 = value;
this.OnPropertyChanged();
}
}
}
private Holm holm4;
public Holm Holm4
{
get
{
return holm4;
}
set
{
if (holm4 != value)
{
holm4 = value;
this.OnPropertyChanged();
}
}
}
}
Xaml并不重要,尚未完成。到目前为止,我已用此代码解决了这个问题:
<CheckBox Content="Sensor1.1" IsChecked="{Binding HolmList[0].Sensor1.IsOnline}"/>
<TextBlock Text="{Binding HolmList[0].Sensor1.IsOnline, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<CheckBox Content="Sensor1.2" IsChecked="{Binding HolmList[0].Sensor2.IsOnline}"/>
<TextBlock Text="{Binding HolmList[0].Sensor2.IsOnline, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<TextBlock Text="{Binding HolmList[0].IsOnline, UpdateSourceTrigger=PropertyChanged}" />
所有我想要的是Holms IsOnline-Property在其中一个Sensors IsOnline-Property更改为false时更改为false ...但它只是不会!
知道这是很多代码,但我实际上并不确定错误的位置。 另外:在我看来,我的分类有多余的OnPropertyChange()调用......但是我不确定是否会发生这种情况。
我真的很感谢你对此有所帮助!
答案 0 :(得分:2)
public class EnhancedObservableCollection<T> : ObservableCollection<T>
where T : INotifyPropertyChanged
{
public EnhancedObservableCollection(bool isCollectionChangedOnChildChange)
{
IsCollectionChangedOnChildChange = isCollectionChangedOnChildChange;
}
public EnhancedObservableCollection(List<T> list, bool isCollectionChangedOnChildChange) : base(list)
{
IsCollectionChangedOnChildChange = isCollectionChangedOnChildChange;
}
public EnhancedObservableCollection(IEnumerable<T> collection, bool isCollectionChangedOnChildChange) : base(collection)
{
IsCollectionChangedOnChildChange = isCollectionChangedOnChildChange;
}
public bool IsCollectionChangedOnChildChange { get; set; }
public event EventHandler<string> ChildChanged;
protected override void RemoveItem(int index)
{
var item = Items[index];
item.PropertyChanged -= ItemOnPropertyChanged;
base.RemoveItem(index);
}
private void ItemOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
var handler = ChildChanged;
if (handler != null)
{
handler(this, propertyChangedEventArgs.PropertyName);
}
if (IsCollectionChangedOnChildChange)
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace));
}
}
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
item.PropertyChanged += ItemOnPropertyChanged;
}
}
答案 1 :(得分:2)
绑定到HolmList[0].IsOnline
的TextBlock没有更新,因为IsOnline
上的Holm
没有通知其值已更改。
您可以在TestSensor
中收听PropertyChanged
的{{1}}个活动,并在其中一个TestSensor
IsOnline
时通知TestSensor
属性更改1}}属性改变。
IsOnline