C# - 动态属性和 RaisePropertyChanged

标签 c# binding dynamic-properties

我有以下用于单选按钮绑定(bind)的类

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" />

View 模型

RadioSwitch = new RadioButtonSwitch(
                new Dictionary<string, bool> {{"radio1", true},{"radio2", false}}
                );

我的类(class)中的 RaisePropertyChanged() 遇到问题。我不确定我应该投入什么值(value)来提高变革。

我尝试放置:

  • 项目[]
  • 一个
  • [a]

我不断收到以下错误:

Error

这样,如果发生任何变化,我可以在我的观点中相应地处理它。请不要给我单选按钮列表等的解决方案。

最佳答案

问题在于您正在实现一个索引器,而不是一个普通的属性。尽管绑定(bind)子系统支持索引器,MVVMLightINotifyPropertyChanged不。

如果您想使用索引器,您需要:

  • 使用集合基类,例如 ObservableCollection<T>
  • 实现INotifiyCollectionChanged并引发那个事件

第一个选项不现实,因为您已经派生自 ViewModelBase并且必须继续这样做。自实现INotifiyCollectionChanged以来需要一点工作,最简单的方法是:

  • 将属性添加到 RadioButtonSwitch这是一个可观察的 bool 值集合 ( ObservableCollection<bool> )

然后更改您的绑定(bind)以再添加一个路径元素,您就完成了。

编辑:

根据您的评论并重新阅读您的问题,我认为实现 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;
        }
    }
}

关于C# - 动态属性和 RaisePropertyChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6079224/

相关文章:

c# - 调用位于另一个目录中的 DLL 文件

Java FX 绑定(bind)属性问题

c# - 后面的wpf绑定(bind)代码

angularjs - 嵌套的 AngularJS 重复语句中的动态对象属性

c# - 我如何将 List<Dictionary<string, object>> 转换为 List<[具有动态属性的新类]>

c# - 禁用 GridViewColumn 调整大小

c# - 在基于 Web 的架构上使用 POCO、DTO 和 ViewModel

c# - SerialPort 没有收到任何数据

WPF如何通过DynamicResource为FontSize属性设置pt(12pt等..)

JavaScript 对象 : Dynamically create properties and property names