双向WPF绑定到一个类的属性

问题描述:

我搜索是最好的,我可以一个ObservableCollection的里面,我无法找到一个答案,这个具体的问题,我有... WPF结合似乎是伟大的和所有的,但最终我的头撞墙往往不是。双向WPF绑定到一个类的属性

好吧,我有一个单例类,这是最终是我绑定到一个:

Imports System.ComponentModel 
Imports System.Collections.ObjectModel 

Public Class AmandaSeyfried 
    Implements INotifyPropertyChanged 

    Shared _config As New config 

    Public Event PropertyChanged(sender As Object, E As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged 

    Protected Overridable Sub OnPropertyChanged(propertyName As String) 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) 
    End Sub 

    Private Shared _thisInstance As AmandaSeyfried 

    Protected Sub New() 
     ' initialization goes here 
    End Sub 

    Public Shared Function GetSingleton() As AmandaSeyfried 
     ' initialize object if it hasn't already been done 
     If _thisInstance Is Nothing Then 
      _thisInstance = New AmandaSeyfried 
     End If 

     ' return the initialized instance 
     Return _thisInstance 
    End Function 

    Public Class CountryTranslation 
     Implements INotifyPropertyChanged 

     Private Property _englishCountryName As String = "" 
     Public Property EnglishCountryName As String 
      Get 
       Return _EnglishCountryName 
      End Get 
      Set(value As String) 
       If _englishCountryName <> value Then 
        _englishCountryName = value 
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("EnglishCountryName")) 
       End If 
      End Set 
     End Property 

     Private Property _foreignCountryName As String = "" 
     Public Property ForeignCountryName As String 
      Get 
       Return _foreignCountryName 
      End Get 
      Set(value As String) 
       If _foreignCountryName <> value Then 
        _foreignCountryName = value 
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("ForeignCountryName")) 
       End If 
      End Set 
     End Property 

     Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged 
    End Class 

    Private WithEvents _countryTranslations As New ObservableCollection(Of CountryTranslation) 
    Public Property CountryTranslations As ObservableCollection(Of CountryTranslation) 
     Get 
      If _config.GetKeyTextValue("countryTranslations") <> "" Then 
       Dim reader As New IO.StringReader(_config.GetKeyTextValue("countryTranslations")) 
       Dim Serializer As New Xml.Serialization.XmlSerializer(_countryTranslations.GetType) 
       _countryTranslations = Serializer.Deserialize(reader) 
      End If 

      Return _countryTranslations 
     End Get 
     Set(value As ObservableCollection(Of CountryTranslation)) 
      _countryTranslations = value 
      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("CountryTranslations")) 
     End Set 
    End Property 

    Private Sub CountryTranslationCollectionChanged(sender As Object, e As Specialized.NotifyCollectionChangedEventArgs) Handles _countryTranslations.CollectionChanged 
     Dim newStringWriter As New IO.StringWriter 
     Dim NewSerializer As New Xml.Serialization.XmlSerializer(_countryTranslations.GetType) 
     NewSerializer.Serialize(newStringWriter, _countryTranslations) 
     _config.SaveKeyTextValue("countryTranslations", newStringWriter.ToString) 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("CountryTranslations")) 
    End Sub 

End Class 

_config是一个名不副实的辅助类存储和从本地SQLCE实例中检索数据。本质上,对象序列化,存储在数据库中,然后拉出DB的需要它的任何时间和反序列化回到对象。总而言之,它似乎工作得很好。

我的问题是,虽然我可以绑定到对象,并且我可以通过CollectionChangedMethod处理程序监视何时在WPF DataGrid中添加一行,但CountryTranslation的两个属性中的任何一个都不是改变。

我的其他相关代码是... XAML ...显然更多,但我不相信绑定的XAML部分是责任,所以我将它修剪到相关:

<toolkit:DataGrid Margin="12,12,12,12" ItemsSource="{Binding Path=KarenSmith.CountryTranslations, Mode=TwoWay}" AutoGenerateColumns="False" HorizontalAlignment="Stretch" Width="Auto" SelectionMode="Single"> 
    <toolkit:DataGrid.Columns> 
     <toolkit:DataGridTextColumn Width="283" Binding="{Binding EnglishCountryName,Mode=TwoWay}" /> 
     <toolkit:DataGridTextColumn Width="283" Binding="{Binding ForeignCountryName,Mode=TwoWay}" /> 
    </toolkit:DataGrid.Columns> 
</toolkit:DataGrid> 

而且简单好用的代码隐藏:

Public Class Preferences 

    Public Property KarenSmith As AmandaSeyfried = AmandaSeyfried.GetSingleton 

    Sub New() 

     ' This call is required by the designer. 
     InitializeComponent() 

     ' Add any initialization after the InitializeComponent() call. 
     DataContext = Me 

    End Sub 

    Private Sub Close_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) 
     Me.Close() 
    End Sub 
End Class 

如果我扔在吸气和CountryTranslation类的二传手一些破发点,我可以当他们被改变(通过监测数据网格,所以绑定正在工作),但尝试我可能无法弄清楚如何在此基础上提出事件回到主类中以随后更新数据存储以显示更改。

+0

CollectionChanged发生集合更改时(不是集合内的项目属性)。更新国家名称属性中的数据存储。 –

平时我一个CollectionChanged事件添加到ObservableCollection,当得到补充,他们这附加一个PropertyChanged事件,它的项目,该事件听众收听更改,并根据需要将处理它们。

下面是一个例子:(希望语法是正确的,因为我只是跑它通过一个C#到VB.Net转换器)

Public Sub New() 
    AddHandler MyCollection.CollectionChanged, AddressOf MyCollection_CollectionChanged 
End Sub 

Private Sub MyCollection_CollectionChanged(sender As Object, e As CollectionChangedEventArgs) 
    If e.NewItems IsNot Nothing Then 
     For Each item As MyItem In e.NewItems 
      AddHandler item.PropertyChanged, AddressOf MyItem_PropertyChanged 
     Next 
    End If 

    If e.OldItems IsNot Nothing Then 
     For Each item As MyItem In e.OldItems 
      RemoveHandler item.PropertyChanged, AddressOf MyItem_PropertyChanged 
     Next 
    End If 
End Sub 

Private Sub MyItem_PropertyChanged(sender As Object, e As PropertyChangedEventArgs) 
    If e.PropertyName = "Some Property" Then 
     DoWork() 
    End If 
End Sub 

C#的版本是这样的:

public MyViewModel() 
{ 
    MyCollection.CollectionChanged += MyCollection_CollectionChanged; 
} 

void MyCollection_CollectionChanged(object sender, CollectionChangedEventArgs e) 
{ 
    if (e.NewItems != null) 
     foreach(MyItem item in e.NewItems) 
      item.PropertyChanged += MyItem_PropertyChanged; 

    if (e.OldItems != null) 
     foreach(MyItem item in e.OldItems) 
      item.PropertyChanged -= MyItem_PropertyChanged; 
} 

void MyItem_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    if (e.PropertyName == "Some Property") 
     DoWork(); 
} 
+0

谢谢!这使我了解如何将事件处理程序添加到Observable集合中的项目。真棒。 –