2011-11-17 62 views
1

我搜索是最好的,我可以一個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發生集合更改時(不是集合內的項目屬性)。更新國家名稱屬性中的數據存儲。 –

回答

2

平時我一個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集合中的項目。真棒。 –