Я создал базовый класс, который реализует интерфейс INotifyPropertyChanged
. Этот класс также содержит общую функцию SetProperty
, чтобы установить значение любого свойства и при необходимости поднять событие PropertyChanged
.Свойство против переменной как параметр ByRef
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
Тогда у меня есть третий класс, который наследуется от базового класса и использует класс хранения данных. Этот третий класс должен быть ViewModel для окна WPF.
Я не перечисляю код для класса 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
, эти значения должны отображаться в моем окне.
Но в моем окне отображается только значение «Текст2».
Стоимость недвижимости Text1
является «Text1», но кажется, что событие PropertyChanged
для этого свойства поднято до того, как собственность приобретет ее значение.
Есть ли способ изменить функцию SetProperty
в моем базовом классе, чтобы поднять PropertyChanged
после того, как недвижимость получила свое значение?
Благодарим за помощь.
http://stackoverflow.com/a/4520101/17034 –