双向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类的二传手一些破发点,我可以当他们被改变(通过监测数据网格,所以绑定正在工作),但尝试我可能无法弄清楚如何在此基础上提出事件回到主类中以随后更新数据存储以显示更改。
平时我一个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();
}
谢谢!这使我了解如何将事件处理程序添加到Observable集合中的项目。真棒。 –
CollectionChanged发生集合更改时(不是集合内的项目属性)。更新国家名称属性中的数据存储。 –