INotifyPropertyChanged 已实施但无法正常工作
INotifyPropertyChanged is implemented but not working
我有一个使用 MVVM 模式并实现 INotifyPropertyChanged 的应用程序,但它无法正常工作。基本上当我从列表中选择一个 Wine 并单击 'open' 时,另一个用户控件应该加载所有填写的详细信息。
我学习了 pluralsight 课程,并尝试对其进行调整并创建自己的东西。我已经浏览了 pluralsight 课程的源代码和堆栈溢出问题很多个小时,但看不出我遗漏了什么。在这里发疯.. :(
经过大量搜索,我知道我的数据绑定工作正常,因为我可以像这样强制更新目标:
txtWijnNaam.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
我还尝试将 INotifyPropertyChanged 添加到我的 Wine 模型 class 以及视图模型中,但这没有用。而且它在 pluralsight 课程的工作源代码中也没有像这样使用,所以没有必要。
我正在使用的视图模型:
class WineDetailViewModel : ViewModelBase
{
private readonly string _baseUri = "https://localhost/api/wines";
private IEventAggregator _eventAggregator;
public WineDetailViewModel()
{
_eventAggregator = EventAggregatorSingleton.Instance;
_eventAggregator.GetEvent<OpenWineDetailViewEvent>().Subscribe(OnOpenWineDetailView);
}
private void OnOpenWineDetailView(int wineId)
{
_wine = ApiHelper.GetApiResult<Wine>($"{ _baseUri}/{wineId}");
}
private Wine _wine;
public Wine WineFull
{
get { return _wine; }
set
{
_wine = value;
OnPropertyChanged();
}
}
}
它继承自的基础 class,实现了 INotifyPropertyChanged 接口:
class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我的 Xaml 文件的一部分,我尝试设置 updateSourceTrigger,就像我在此处看到的一些答案一样,但这也没有帮助:
<UserControl x:Class="WineGUI.View.WineDetailView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WineGUI.View"
xmlns:ViewModels="clr-namespace:WineGUI.ViewModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<ViewModels:WineDetailViewModel/>
</UserControl.DataContext>
<StackPanel>
<Grid Margin="5">
<TextBlock Text="Naam :" VerticalAlignment="Center"/>
<TextBox Grid.Column="1" Name="txtWijnNaam" Margin="5" Text="{Binding WineFull.Name, Mode=TwoWay}"/>
<TextBlock Grid.Row="1" Text="Jaar :" VerticalAlignment="Center"/>
<TextBox Grid.Row="1" Grid.Column="1" Name="txtWijnYear" Margin="5" Text="{Binding WineFull.Year, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Row="2" Text="Prijs :" VerticalAlignment="Center"/>
我确实注意到我的 WineFull 属性 的 OnPropertyChanged() 方法从未被调用,但我不明白为什么。 pluralsight 课程具有相同的设置(当然除了一些命名之外)并且效果很好..
如有任何帮助,我们将不胜感激。如果我需要添加更多信息或代码,请告诉我。
您正在设置支持字段的值而不是 属性,因此永远不会调用 OnPropertyChanged 方法。
您可以在 OnOpenWineDetailView 方法中为 WineFull 属性 调用 OnPropertyChanged:
private void OnOpenWineDetailView(int wineId)
{
_wine = ApiHelper.GetApiResult<Wine>($"{ _baseUri}/{wineId}");
OnPropertyChanged(nameof(WineFull));
}
或者您可以使用 属性:
private void OnOpenWineDetailView(int wineId)
{
WineFull= ApiHelper.GetApiResult<Wine>($"{ _baseUri}/{wineId}");
}
我有一个使用 MVVM 模式并实现 INotifyPropertyChanged 的应用程序,但它无法正常工作。基本上当我从列表中选择一个 Wine 并单击 'open' 时,另一个用户控件应该加载所有填写的详细信息。
我学习了 pluralsight 课程,并尝试对其进行调整并创建自己的东西。我已经浏览了 pluralsight 课程的源代码和堆栈溢出问题很多个小时,但看不出我遗漏了什么。在这里发疯.. :(
经过大量搜索,我知道我的数据绑定工作正常,因为我可以像这样强制更新目标:
txtWijnNaam.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
我还尝试将 INotifyPropertyChanged 添加到我的 Wine 模型 class 以及视图模型中,但这没有用。而且它在 pluralsight 课程的工作源代码中也没有像这样使用,所以没有必要。
我正在使用的视图模型:
class WineDetailViewModel : ViewModelBase
{
private readonly string _baseUri = "https://localhost/api/wines";
private IEventAggregator _eventAggregator;
public WineDetailViewModel()
{
_eventAggregator = EventAggregatorSingleton.Instance;
_eventAggregator.GetEvent<OpenWineDetailViewEvent>().Subscribe(OnOpenWineDetailView);
}
private void OnOpenWineDetailView(int wineId)
{
_wine = ApiHelper.GetApiResult<Wine>($"{ _baseUri}/{wineId}");
}
private Wine _wine;
public Wine WineFull
{
get { return _wine; }
set
{
_wine = value;
OnPropertyChanged();
}
}
}
它继承自的基础 class,实现了 INotifyPropertyChanged 接口:
class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我的 Xaml 文件的一部分,我尝试设置 updateSourceTrigger,就像我在此处看到的一些答案一样,但这也没有帮助:
<UserControl x:Class="WineGUI.View.WineDetailView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WineGUI.View"
xmlns:ViewModels="clr-namespace:WineGUI.ViewModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<ViewModels:WineDetailViewModel/>
</UserControl.DataContext>
<StackPanel>
<Grid Margin="5">
<TextBlock Text="Naam :" VerticalAlignment="Center"/>
<TextBox Grid.Column="1" Name="txtWijnNaam" Margin="5" Text="{Binding WineFull.Name, Mode=TwoWay}"/>
<TextBlock Grid.Row="1" Text="Jaar :" VerticalAlignment="Center"/>
<TextBox Grid.Row="1" Grid.Column="1" Name="txtWijnYear" Margin="5" Text="{Binding WineFull.Year, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Row="2" Text="Prijs :" VerticalAlignment="Center"/>
我确实注意到我的 WineFull 属性 的 OnPropertyChanged() 方法从未被调用,但我不明白为什么。 pluralsight 课程具有相同的设置(当然除了一些命名之外)并且效果很好..
如有任何帮助,我们将不胜感激。如果我需要添加更多信息或代码,请告诉我。
您正在设置支持字段的值而不是 属性,因此永远不会调用 OnPropertyChanged 方法。
您可以在 OnOpenWineDetailView 方法中为 WineFull 属性 调用 OnPropertyChanged:
private void OnOpenWineDetailView(int wineId)
{
_wine = ApiHelper.GetApiResult<Wine>($"{ _baseUri}/{wineId}");
OnPropertyChanged(nameof(WineFull));
}
或者您可以使用 属性:
private void OnOpenWineDetailView(int wineId)
{
WineFull= ApiHelper.GetApiResult<Wine>($"{ _baseUri}/{wineId}");
}