2010-04-14 28 views
4

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

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

回答

8

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

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

的MainPage: -

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被通知。

相关问题