Home > front end >  WPF vb.Net DataBinding INotifyPropertyChanged
WPF vb.Net DataBinding INotifyPropertyChanged

Time:05-30

I made a little App for practicing Data Binding in WPF vb.NET Framework. It contains 3 Windows, One with a Slider, one with a TextBox and one with 3 Buttons which opens the other two Windows.

MainWindow.vb:

Imports System.ComponentModel
Imports WPF_Viewmodel_Test.ViewModel_Namespace
Imports GalaSoft.MvvmLight.Command

Public Class MainWindow

    Private viewModel As New ViewModel()

    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub SettingsWindowButton_OnClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim settingsWindow = New SettingsWindow()
        settingsWindow.DataContext = viewModel
        settingsWindow.Show()
    End Sub

    Private Sub BoundWindowButton_OnClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim boundWindow = New BoundWindow()
        boundWindow.DataContext = viewModel
        boundWindow.Show()
    End Sub

End Class

Namespace ViewModel_Namespace

    Public Class ViewModel
        Implements INotifyPropertyChanged

#Region "Property"

        Public Sub New()
        End Sub

        Private _fontSizeSetting As Integer = 10

        Public Event PropertyChanged As PropertyChangedEventHandler _
        Implements INotifyPropertyChanged.PropertyChanged

        Public Property FontSizeSetting As Integer
            Get
                Return _fontSizeSetting
            End Get
            Set(value As Integer)
                _fontSizeSetting = value
                OnPropertyChanged("FontSizeSetting")
            End Set
        End Property

        Protected Overridable Sub OnPropertyChanged(propertyName As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
        End Sub

#End Region

#Region "Command"

        Private _changeFontsize As ICommand

        Public ReadOnly Property ChangeFontsizeCommand() As ICommand
            Get
                If _changeFontsize Is Nothing Then
                    _changeFontsize = New RelayCommand(Sub() ChangeFontsize(), Function() True)
                End If

                Return _changeFontsize
            End Get
        End Property

        Private Sub ChangeFontsize()
            FontSizeSetting = 50
        End Sub

#End Region

    End Class

End Namespace

MainWindow.xaml:

<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:cmd="clr-namespace:WPF_Viewmodel_Test.ViewModel_Namespace"
        mc:Ignorable="d"
        Title="MainWindow" Height="172" Width="504">

    <Window.Resources>
        <cmd:ViewModel x:Key="mycommand"></cmd:ViewModel>
    </Window.Resources>
    
    <StackPanel>
        <Button Content="Settings Window" Click="SettingsWindowButton_OnClick"/>
        <Button Content="Bound Window" Click="BoundWindowButton_OnClick"/>
        <Button Content="Change Fontsize" Click="ChangeButton_OnClick" Command="{Binding Source={StaticResource mycommand}, Path=WebSeiteAufrufenCommand}"/>
    </StackPanel>
</Window>

SettingsWindow.xaml:

<Window x:Class="SettingsWindow"
        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"
        mc:Ignorable="d"
        Title="SettingsWindow" Height="450" Width="800" HorizontalAlignment="Center" VerticalAlignment="Center">

    <Grid>
        <Slider x:Name="slider1" Value="{Binding FontSizeSetting, Mode=TwoWay}" Minimum="10" Maximum="100" />
    </Grid>
    
</Window>

BoundWindow.xaml:

<Window x:Class="BoundWindow"
        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"
        mc:Ignorable="d"
        Title="Boundwindow" Height="450" Width="800">

    <Grid>
        <TextBox FontSize="{Binding FontSizeSetting, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" Text="This is an Example Text"/>
    </Grid>
    
</Window>

The Binding works fine and the Font Size of the Text Box gets adjusted according to the Slider- Value. Now I want to change the Property 'FonSizeSetting' via a Button in the MainWindow. The Property is set to 50 by a ICommand.

FontSizeSetting = 50

I raise the PropertyChanged Event but still the both Windows do not update the Font Size or Sliderposition. I tried already setting the DataContext directly in XAML via Window.DataContext but this resulted in a non-Working Binding.

Can anyone please explain to me what I'm doing wrong here?

CodePudding user response:

you have 2 instances of ViewModel in MainWindow: one in Resources <cmd:ViewModel x:Key="mycommand"></cmd:ViewModel> and one in a private field: Private viewModel As New ViewModel()

you call command from resource instance which is not bount to other windows.

change MainWindow like this:

<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:cmd="clr-namespace:WPF_Viewmodel_Test.ViewModel_Namespace"
        mc:Ignorable="d"
        Title="MainWindow" Height="172" Width="504">

    <Window.DataContext>
        <cmd:ViewModel />
    </Window.DataContext>
    
    <StackPanel>
        <Button Content="Settings Window" Click="SettingsWindowButton_OnClick"/>
        <Button Content="Bound Window" Click="BoundWindowButton_OnClick"/>
        <Button Content="Change Fontsize" Click="ChangeButton_OnClick" 
                Command="{Binding Path=ChangeFontsizeCommand}"/>
    </StackPanel>
</Window>

and

Public Class MainWindow

    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub SettingsWindowButton_OnClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim settingsWindow = New SettingsWindow()
        settingsWindow.DataContext = DataContext 
        settingsWindow.Show()
    End Sub

    Private Sub BoundWindowButton_OnClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim boundWindow = New BoundWindow()
        boundWindow.DataContext = DataContext 
        boundWindow.Show()
    End Sub

End Class
  • Related