我想创建一个通用的ObservableItem类,我想了解如何实现它。 我希望它是通用的,以便我可以将它用于所有类型的类型(如果可能的话)。 我想创建它的原因是能够将多个控件绑定到一个数组,而不是为每个绑定创建属性。 (我想要一个双向绑定,这样当源更新时,控件将通过PropertyChanged事件通知)。 我开始创建课程,但我不知道要添加什么实现,以使其适用于每种类型的用途。
public struct ObservableItem<T> : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private T _item;
private T Item
{
get {
return _item;
}
set
{
_item = value;
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(_item.ToString()));
}
}
public static implicit operator T(ObservableItem<T> value)
{
return value.Item;
}
public static implicit operator ObservableItem<T>(T value)
{
var ret = new ObservableItem<T>();
ret.Item = value;
return ret;
}
}
我希望该课程的用途适合所有事情:
ObservableItem<int> value1 = 5;
ObservableItem<int>[] aValue = new ObservableItem<int>[5];
aValue[0] = 4;
aValue[1] = 5;
aValue[2] = aValue[0] + aValue[1];
aValue[3] = aValue[0] * aValue[1];
ObservableItem<bool> value2;
value2 = !value2;
ObservableItem<bool>[] Channels = new ObservableItem<bool>[4];
// and more uses
Xaml绑定:
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="0,0,0,10">
<CheckBox IsChecked="{Binding Channels[0]}" Content="Channel 1" Style="{StaticResource Channels}"></CheckBox>
<CheckBox IsChecked="{Binding Channels[1]}" Content="Channel 2" Style="{StaticResource Channels}"></CheckBox>
<CheckBox IsChecked="{Binding Channels[2]}" Content="Channel 3" Style="{StaticResource Channels}"></CheckBox>
<CheckBox IsChecked="{Binding Channels[3]}" Content="Channel 4" Style="{StaticResource Channels}"></CheckBox>
</StackPanel>
提前致谢。
答案 0 :(得分:0)
我找到了解决问题的方法,所以我将其作为每个人使用的答案发布。
我没有找到一种方法来创建一个通用的ObservableItem,它允许我将它用作每个对象。像:
public ObservableItem<bool> value {get;set}
并在xaml中直接绑定到&#39;值&#39;而不是&#39; value.Item&#39;。 每当我用隐式运算符更改值时,绑定也会停止。
value = !value; //kills the binding - because the object is replaced
所以,我编写了一个ObservableItemCollection,它继承了ObservableCollection并重新实现了ObservableCollection的索引器操作符,它基于Collection,因此每个set操作都将调用PropertyChanged事件处理程序。
public class ObservableItemCollection<T> : ObservableCollection<T>
{
private string propertyName;
public ObservableItemCollection(string propertyName, int numberOfDefaultItemsToAdd = 0)
: base()
{
this.propertyName = propertyName;
this.AddDefaults(numberOfDefaultItemsToAdd);
}
public ObservableItemCollection(IEnumerable<T> collection, string propertyName, int numberOfDefaultItemsToAdd = 0)
: base(collection)
{
this.propertyName = propertyName;
this.AddDefaults(numberOfDefaultItemsToAdd);
}
public ObservableItemCollection(List<T> list, string propertyName, int numberOfDefaultItemsToAdd = 0)
: base(list)
{
this.propertyName = propertyName;
this.AddDefaults(numberOfDefaultItemsToAdd);
}
public new T this[int index]
{
get { return base[index]; }
set
{
base[index] = value;
// Call ObservableCollection OnPropertyChanged method.
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
}
public void AddDefaults(int numberOfDefaultItemsToAdd = 1)
{
if (numberOfDefaultItemsToAdd < 0) throw new ArgumentOutOfRangeException("numberOfItemsToAdd must be a non-negative number");
for(int i = 0; i < numberOfDefaultItemsToAdd; ++i)
base.Add(default(T));
}
}
这样我可以像任何类数组一样使用集合,并直接绑定到项目。
public ObservableItemCollection<bool> Channels { get; set; }
在xaml:
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<CheckBox Content="Channel 1" IsChecked="{Binding Path=Channels[0]}" Style="{StaticResource Channels}"></CheckBox>
<CheckBox Content="Channel 2" IsChecked="{Binding Path=Channels[1]}" Style="{StaticResource Channels}"></CheckBox>
</StackPanel>
&GT;