我有以下用于单选按钮绑定的课程
public class RadioButtonSwitch : ViewModelBase
{
IDictionary<string, bool> _options;
public RadioButtonSwitch(IDictionary<string, bool> options)
{
this._options = options;
}
public bool this[string a]
{
get
{
return _options[a];
}
set
{
if (value)
{
var other = _options.Where(p => p.Key != a).Select(p => p.Key).ToArray();
foreach (string key in other)
_options[key] = false;
_options[a] = true;
RaisePropertyChanged("XXXX");
else
_options[a] = false;
}
}
}
XAML
<RadioButton Content="Day" IsChecked="{Binding RadioSwitch[radio1], Mode=TwoWay}" GroupName="Monthly" HorizontalAlignment="Left" VerticalAlignment="Center" />
视图模型
RadioSwitch = new RadioButtonSwitch(
new Dictionary<string, bool> {{"radio1", true},{"radio2", false}}
);
我的班级中遇到RaisePropertyChanged()问题。我不确定我应该采取什么价值来提高变化。
我尝试过:
我一直收到以下错误:
如果发生任何变化,我可以在相应的视图中处理。请不要给我列表的单选按钮等解决方案。
答案 0 :(得分:2)
问题是您正在实施索引器,而不是普通的属性。虽然绑定子系统支持索引器,但 MVVMLight 和INotifyPropertyChanged
却不支持。
如果您想使用索引器,则需要:
ObservableCollection<T>
INotifiyCollectionChanged
并提高 事件第一个选项是不现实的,因为您已经从ViewModelBase
派生而且必须继续这样做。由于实施INotifiyCollectionChanged
只是一点点工作,最简单的方法是:
RadioButtonSwitch
添加属性,该属性是可观察的布尔值集合(ObservableCollection<bool>
)然后更改绑定以添加一个路径元素,您就完成了。
修改强>
根据您的评论并重新阅读您的问题,我认为实施INotifyCollectionChanged
是最简单的。以下是对RadioButtonSwitch
类的重写,实际上不再需要从 MVVMLight 基类派生,尽管如果你愿意,你仍然可以。
细心的读者会注意到,当修改集合的任何元素时,我们会使用大锤并“重置”整个集合。这不只是懒惰;这是因为索引器使用字符串索引而不是整数索引,INotifyCollectionChanged
不支持。结果,当任何改变时,我们只是举起手来说整个系列已经改变了。
public class RadioButtonSwitch : INotifyCollectionChanged
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected void RaiseCollectionChanged()
{
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
IDictionary<string, bool> _options;
public RadioButtonSwitch(IDictionary<string, bool> options)
{
this._options = options;
}
public bool this[string a]
{
get
{
return _options[a];
}
set
{
if (value)
{
var other = _options.Where(p => p.Key != a).Select(p => p.Key).ToArray();
foreach (string key in other)
_options[key] = false;
_options[a] = true;
RaiseCollectionChanged();
}
else
_options[a] = false;
}
}
}
答案 1 :(得分:2)
GalaSoft.MvvmLight在提升PropertyChanged
事件之前有以下代码来检查属性名称。
public void VerifyPropertyName(string propertyName)
{
if (GetType().GetProperty(propertyName) == null)
throw new ArgumentException("Property not found", propertyName);
}
GetType().GetProperty("Item[]")
显然会返回null
这就是它失败的原因。
我认为,对您而言最快的解决方法是不使用此库中的ViewModelBase
,而是实现您自己的版本,但不会检查:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
如果您实施此课程,则可以运行RaisePropertyChanged("Item[]")
。