代码之家  ›  专栏  ›  技术社区  ›  Carl Rippon

在Silverlight中绑定到已更改inotifyPropertyChanged的词典

  •  4
  • Carl Rippon  · 技术社区  · 15 年前

    在silverlight中,我无法将inotifyproperty更改为像绑定到字典时所希望的那样工作。在下面的示例中,页面可以绑定到字典,但是当我更改其中一个文本框的内容时,不会调用customproperties属性setter。仅当设置了customproperties时才调用customproperties属性setter,而不是在设置了其中的值时调用。我正在尝试对字典值进行一些验证,因此希望在字典中的每个值更改时运行一些代码。我能在这里做点什么吗?

    C.*

    public partial class MainPage : UserControl
    {
    
        public MainPage()
        {
            InitializeComponent();
    
            MyEntity ent = new MyEntity();
            ent.CustomProperties.Add("Title", "Mr");
            ent.CustomProperties.Add("FirstName", "John");
            ent.CustomProperties.Add("Name", "Smith");
    
            this.DataContext = ent;
        }
    
    }
    
    public class MyEntity : INotifyPropertyChanged
    {
    
        public event PropertyChangedEventHandler System.ComponentModel.INotifyPropertyChanged.PropertyChanged;
        public delegate void PropertyChangedEventHandler(object sender, System.ComponentModel.PropertyChangedEventArgs e);
    
        private Dictionary<string, object> _customProps;
        public Dictionary<string, object> CustomProperties {
            get {
                if (_customProps == null) {
                    _customProps = new Dictionary<string, object>();
                }
                return _customProps;
            }
            set {
                _customProps = value;
                if (PropertyChanged != null) {
                    PropertyChanged(this, new PropertyChangedEventArgs("CustomProperties"));
                }
            }
        }
    
    }
    

    VB

    Partial Public Class MainPage
        Inherits UserControl
    
        Public Sub New()
            InitializeComponent()
    
            Dim ent As New MyEntity
            ent.CustomProperties.Add("Title", "Mr")
            ent.CustomProperties.Add("FirstName", "John")
            ent.CustomProperties.Add("Name", "Smith")
    
            Me.DataContext = ent
        End Sub
    
    End Class
    
    Public Class MyEntity
        Implements INotifyPropertyChanged
    
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    
        Private _customProps As Dictionary(Of String, Object)
        Public Property CustomProperties As Dictionary(Of String, Object)
            Get
                If _customProps Is Nothing Then
                    _customProps = New Dictionary(Of String, Object)
                End If
                Return _customProps
            End Get
            Set(ByVal value As Dictionary(Of String, Object))
                _customProps = value
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("CustomProperties"))
            End Set
        End Property
    
    End Class
    

    XAML

    <TextBox Height="23" Name="TextBox1" Text="{Binding Path=CustomProperties[Title], Mode=TwoWay}" />
    <TextBox Height="23" Name="TextBox2" Text="{Binding Path=CustomProperties[FirstName], Mode=TwoWay}" />
    <TextBox Height="23" Name="TextBox3" Text="{Binding Path=CustomProperties[Name], Mode=TwoWay}" />
    
    2 回复  |  直到 15 年前
        1
  •  6
  •   dtb    15 年前

    集合需要实现 INotifyCollectionChanged interface 除了 INotifyPropertyChanged interface 以支持数据绑定。这个 ObservableCollection class 为类似于列表的集合实现它们,但我相信在.NET框架中没有类似于字典的集合可以做到这一点。你可能得自己实现它。

        2
  •  8
  •   AnthonyWJones    15 年前

    这里有一个(有些过于简单)的解决方案。

    public class MyEntity : INotifyPropertyChanged
    {
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private readonly Dictionary<string, object> _customProps = new Dictionary<string, object>();
    
        public void AddCustomProperty(string key, object value)
        {
            _customProps.Add(key, value);
        }
    
        public object this[string key]
        {
            get { return _customProps[key]; }
            set
            {
                // The validation code of which you speak here.
                _customProps[key] = value;
                NotifyPropertyChanged("Item[" + key "]");
            }
        }
    
        private void NotifyPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
    

    主页:

        public MainPage()
        {
            InitializeComponent();
    
            MyEntity ent = new MyEntity();
            ent.AddCustomProperty("Title", "Mr");
            ent.AddCustomProperty("FirstName", "John");
            ent.AddCustomProperty("Name", "Smith");
    
            this.DataContext = ent;
    
        }
    

    主页xaml:-

            <TextBox Height="23" Name="TextBox1" Text="{Binding [Title], Mode=TwoWay}" />
            <TextBox Height="23" Name="TextBox2" Text="{Binding [FirstName], Mode=TwoWay}" />
            <TextBox Height="23" Name="TextBox3" Text="{Binding [Name], Mode=TwoWay}" />
    

    对于您的问题,重要的是您的代码涉及到将属性值分配到字典中。最初你的代码暴露了 Dictionary ,所有的分配工作都通过了框架组件代码。在这个版本中 MyEntity 有一个字符串索引器,其中直接分配自定义属性,并且 词典 是私人的。

    注意执行 INotifyPropertyChanged 不必回答你的具体问题,但我想你会需要它的。例如,如果将新值重新分配给自定义属性,则需要通知ui。