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