【问题标题】:Custom INPC type in WPF backed by dictionary由字典支持的 WPF 中的自定义 INPC 类型
【发布时间】:2013-04-29 19:46:36
【问题描述】:

我想要这个动态类

class FooViewModel : INotifyPropertyChanged {

    private Dictionary<string, object> data = new Dictionary<string, object>();

    public void Set(string path, object value)
    {
        data[path]=value;
        NotifyPropertyChanged(path);
    }

    public object Get(string path)
    {
        if(data.ContainsKey(path)){
            return data[path];
        }else{
            return null;
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged( String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

如果我将它设置为某些 WPF XAML 的 DataContext,我想成为 能够将数据绑定到 two way bind 到其中的键。

<TextBox Text="{Bind Path=Foo}"/>
<TextBox Text="{Bind Path=Bar}"/>

在我的视图模型代码中的某个地方我将拥有

var vm = new FooViewModel();
vm.Set("Foo", "Yeah!");
vm.Set("Bar", "Booh!");

这样自定义绑定有什么技巧?

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    您可以从DynamicObject 派生您的类或实现IDynamicMetaObjectProvider。这应该可以解决问题,因为 WPF 支持绑定到动态对象。

    http://www.shujaat.net/2012/09/dynamicobject-wpf-binding.html 就是一个很好的例子

    class ViewModelBase : DynamicObject, INotifyPropertyChanged
    {
        #region Private Members
    
        private Dictionary<string, object> _dynamicProperties;
    
        #endregion Private Members
    
        #region Constructor
    
        public ViewModelBase(IEnumerable<string> propertyNames)
        {
            if (propertyNames == null)
            {
                throw new Exception("propertyNames is empty");
            }
    
            _dynamicProperties = new Dictionary<string, object>();
            propertyNames
                .ToList()
                .ForEach(propName => _dynamicProperties.Add(propName, null));
        }
        #endregion Constructor
    
        #region Public Methods
    
        public void SetPropertyValue(string propertyName, object value)
        {
            if (_dynamicProperties.ContainsKey(propertyName))
            {
                _dynamicProperties[propertyName] = value;
                OnPropertyChanged(propertyName);
            }
        }
    
        public object GetPropertyValue(string propertyName)
        {
            return _dynamicProperties.ContainsKey(propertyName) ? _dynamicProperties[propertyName] : null;
        }
    
        #endregion Public Methods
    
        #region DynamicObject Overriden Members
    
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            bool ret = base.TryGetMember(binder, out result);
    
            if (ret == false)
            {
                result = GetPropertyValue(binder.Name);
                if (result != null)
                {
                    ret = true;
                }
            }
    
            return ret;
        }
    
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            bool ret = base.TrySetMember(binder, value);
    
            if (ret == false)
            {
                SetPropertyValue(binder.Name, value);
                ret = true;
            }
    
            return ret;
        }
    
        #endregion DynamicObject Overriden Members
    
        #region INotifyPropertyChanged Implementation
    
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    
        #endregion INotifyPropertyChanged Implementation
    }
    

    【讨论】:

    • 因为 WPF 支持绑定到动态对象 - 你能给我们这个声明的来源吗?
    • 我想在某个地方看到一个示例以及 INPC 支持。
    • blogs.msdn.com/b/llobo/archive/2009/11/02/… 不确定这是否是官方来源,但我试过了,它可以工作。
    • 在上面的链接中下载示例。 INPC 在 DynamicObjectClass 中实现
    • 有趣,不漂亮...但这绝对可以。 :o)
    猜你喜欢
    • 2010-11-05
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    • 2019-03-08
    • 1970-01-01
    • 2017-05-13
    相关资源
    最近更新 更多