2010-04-14 3 views
4

В silverlight я не могу заставить INotifyPropertyChanged работать так, как я хочу, при привязке к словарю. В приведенном ниже примере страница привязывается к словарю в порядке, но когда я изменяю содержимое одного из текстовых полей, свойство SetProperties не вызывается. Настройщик свойств 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")); 
      } 
     } 
    } 

} 

В.Б.

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

ответ

6

Коллекция должна реализовать INotifyCollectionChanged interface в дополнение к INotifyPropertyChanged interface для поддержки связывания данных. ObservableCollection class реализует их для коллекции, подобной List, но я считаю, что в .NET Framework не существует подобной коллекции словарей, которая делает это. Вы, вероятно, должны реализовать его самостоятельно.

+0

Спасибо, я tweeked реализация dr wpf в ObservableDictionary: http://drwpf.com/blog/2007/09/16/can-i-bind-my-itemscontrol-to-a-dictionary/ –

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 не является обязательной для ответа на ваш конкретный вопрос, но я подозреваю, что вам это нужно. Если, например, вы повторно назначили новое значение настраиваемому свойству, вам нужно, чтобы пользовательский интерфейс был уведомлен.

Смежные вопросы