I created a base class that implements the INotifyPropertyChanged
interface. This class also contains a generic function SetProperty
to set the value of any property and raise the PropertyChanged
event, if necessary.
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
Then I have a class, that is supposed to hold some data. For the sake of simplicity it only contains one property (in this example).
Public Class Item
Public Property Text As String
End Class
Then I have a third class that inherits from the base class and uses the data holding class. This third class is supposed to be a ViewModel for a WPF window.
I don't list the code for the RelayCommand
class, since you probably all have an implementation yourself. Just keep in mind, that this class executes the given function, when the command is executed.
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
And then I have my WPF window that uses the ViewModel class as its 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>
As you can see, this window contains only two TextBoxes and a button. The TextBoxes are bound to the properties Text1
and Text2
and the button is supposed to execute the command TestCommand
.
When the command is executed both properties Text1
and Text2
is given a value. And since both properties raise the PropertyChanged
event, these values should be shown in my window.
But only the value "Text2" is shown in my window.
The value of property Text1
is "Text1", but it seems that the PropertyChanged
event for this property is raised before the property got its value.
Is there any way to change the SetProperty
function in my base class to raise the PropertyChanged
after the property got its value?
Thank you for your help.