簡體   English   中英

使用INotifyPropertyChanged綁定到Silverlight中的字典

[英]Binding to a dictionary in Silverlight with INotifyPropertyChanged

在Silverlight中,我無法讓INotifyPropertyChanged在綁定到字典時像我想要的那樣工作。 在下面的示例中,頁面可以正常綁定到字典,但是當我更改其中一個文本框的內容時,不會調用CustomProperties屬性setter。 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}" />

這是一個(有點過於簡化)的解決方案。

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。

除了INotifyPropertyChanged接口之外,集合還需要實現INotifyCollectionChanged 接口以支持數據綁定。 ObservableCollection類為類似List的集合實現它們,但我相信.NET Framework中沒有類似字典的集合來執行此操作。 您可能必須自己實施它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM