【发布时间】:2017-04-12 08:18:12
【问题描述】:
我创建了一个实现INotifyPropertyChanged 接口的基类。该类还包含一个通用函数SetProperty,用于设置任何属性的值并在必要时引发PropertyChanged 事件。
Public Class BaseClass
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Function SetProperty(Of T)(ByRef storage As T, value As T, <CallerMemberName> Optional ByVal propertyName As String = Nothing) As Boolean
If Object.Equals(storage, value) Then
Return False
End If
storage = value
Me.OnPropertyChanged(propertyName)
Return True
End Function
Protected Overridable Sub OnPropertyChanged(<CallerMemberName> Optional ByVal propertyName As String = Nothing)
If String.IsNullOrEmpty(propertyName) Then
Throw New ArgumentNullException(NameOf(propertyName))
End If
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
然后我有一个类,它应该保存一些数据。为简单起见,它仅包含一个属性(在此示例中)。
Public Class Item
Public Property Text As String
End Class
然后我有第三个类,它继承自基类并使用数据保存类。这第三个类应该是 WPF 窗口的 ViewModel。
我没有列出RelayCommand 类的代码,因为你们可能都有自己的实现。请记住,这个类在执行命令时执行给定的函数。
Public Class ViewModel
Inherits BaseClass
Private _text1 As Item 'data holding class
Private _text2 As String 'simple variable
Private _testCommand As ICommand = New RelayCommand(AddressOf Me.Test)
Public Sub New()
_text1 = New Item
End Sub
Public Property Text1 As String
Get
Return _text1.Text
End Get
Set(ByVal value As String)
Me.SetProperty(Of String)(_text1.Text, value)
End Set
End Property
Public Property Text2 As String
Get
Return _text2
End Get
Set(ByVal value As String)
Me.SetProperty(Of String)(_text2, value)
End Set
End Property
Public ReadOnly Property TestCommand As ICommand
Get
Return _testCommand
End Get
End Property
Private Sub Test()
Me.Text1 = "Text1"
Me.Text2 = "Text2"
End Sub
End Class
然后我的 WPF 窗口使用 ViewModel 类作为其DataContext。
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Text1}" Height="24" Width="100" />
<TextBox Text="{Binding Text2}" Height="24" Width="100" />
<Button Height="24" Content="Fill" Command="{Binding TestCommand}" />
</StackPanel>
</Window>
如您所见,此窗口仅包含两个文本框和一个按钮。文本框绑定到属性Text1 和Text2,并且按钮应该执行命令TestCommand。
当命令执行时,Text1 和 Text2 两个属性都会被赋予一个值。由于这两个属性都会引发PropertyChanged 事件,因此这些值应该会显示在我的窗口中。
但我的窗口中只显示值“Text2”。
属性Text1 的值为“Text1”,但似乎该属性的PropertyChanged 事件在该属性获得其值之前引发。
有什么方法可以在我的基类中更改SetProperty 函数以在属性获得其值后提升PropertyChanged?
感谢您的帮助。
【问题讨论】:
标签: wpf vb.net inotifypropertychanged byref