C# C-动态特性和RaisePropertyChanged
我有下面的类,我使用单选按钮绑定C# C-动态特性和RaisePropertyChanged,c#,binding,dynamic-properties,C#,Binding,Dynamic Properties,我有下面的类,我使用单选按钮绑定 public class RadioButtonSwitch : ViewModelBase { IDictionary<string, bool> _options; public RadioButtonSwitch(IDictionary<string, bool> options) { this._options = options;
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
视图模型
RadioSwitch = new RadioButtonSwitch(
new Dictionary<string, bool> {{"radio1", true},{"radio2", false}}
);
我在课堂上对RaiseProperty的更改有问题。我不确定我应该投入什么样的价值来提高零钱
我试着说:
项目[]
A.
[a]
我不断得到以下错误:
因此,在任何变化的情况下,我可以在我的观点中相应地处理它。请不要为单选按钮列表等提供解决方案。问题在于您正在实现一个索引器,而不是一个普通属性。尽管绑定子系统支持索引器,但MVVMLight和INotifyPropertyChanged不支持 如果要使用索引器,您需要: 使用集合基类,如ObservableCollection 实施InotifyCollectionChanged并引发该事件 第一个选项是不现实的,因为您已经从ViewModelBase派生,并且必须继续这样做。由于实现InotifyCollectionChanged需要一点工作,因此最简单的方法是: 向RadioButtonSwitch添加一个属性,该属性是布尔值的可观察集合ObservableCollection 然后更改绑定以添加一个以上的path元素,就完成了 编辑: 根据您的评论并重新阅读您的问题,我认为实施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;
}
}
}
GalaSoft.MvvmLight具有以下代码,用于在引发PropertyChanged事件之前检查属性名称 GetType.GetPropertyItem[]显然返回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));
}
}
如果实现该类,您将能够运行RaisePropertyChangedItem[]。ViewModelBase在哪里定义?ViewModelBase扩展了GalaSoft.MvvMLight ViewModelBase。它实现INotifyPropertyChanged。RaisePropertyChanged几乎只是调用if PropertyChanged!=空PropertyChangedthis,新PropertyChangedEventArgsproperty;嗯,那么错误是从哪里来的呢?你能发布完整的堆栈跟踪吗?@KirkWoll添加了错误的屏幕截图。我假设发生了错误,因为我没有使用正确的参数调用RaisePropertyChanged。RadioButton绑定到[radio1],我尝试使用它作为属性名,但也不起作用。第二个选项听起来不错。但是,我不知道如何绑定到特定的ObservableCollection行。你有什么例子吗?太好了,这正是我想要的!我不想从头开始实现一切,也不想改变其他地方使用的现有方法。
public void VerifyPropertyName(string propertyName)
{
if (GetType().GetProperty(propertyName) == null)
throw new ArgumentException("Property not found", propertyName);
}
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));
}
}