【问题标题】:Binding to a dictionary in Silverlight with INotifyPropertyChanged使用 INotifyPropertyChanged 绑定到 Silverlight 中的字典
【发布时间】:2011-02-07 20:57:11
【问题描述】:

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

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

【问题讨论】:

    标签: c# .net silverlight data-binding inotifypropertychanged


    【解决方案1】:

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

    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;
    
        }
    

    MainPage 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 有一个字符串索引器,其中直接分配自定义属性并将Dictionary 设为私有。

    请注意,INotifyPropertyChanged 的实现对于回答您的具体问题并不是绝对必要的,但我怀疑您会需要它。例如,如果您将新值重新分配给自定义属性,您会希望 UI 得到通知。

    【讨论】:

      【解决方案2】:

      除了INotifyPropertyChanged interface 之外,集合还需要实现INotifyCollectionChanged interface 以支持数据绑定。 ObservableCollection class 为类似列表的集合实现它们,但我相信 .NET Framework 中没有类似字典的集合可以做到这一点。您可能必须自己实现它。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-13
      • 2023-03-13
      • 2012-12-07
      • 2019-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多