我使用具有 ContentControl 的 MainWindow.xaml 设置了导航。Content 属性绑定到 MainViewModel 中的对象属性。
我有一个具有 UserListViewModel.cs 的 UserListView.xaml 用户控件和一个具有 UserDetailViewModel.cs 类的 UserDetailView.xaml 用户控件。
UserListView 显示从数据库中获取的用户列表。在此屏幕上,您可以单击每个用户的按钮来编辑列表中的该用户。还有一个按钮可以创建新用户。每个按钮都会将您带到 UserDetail 屏幕,您可以在其中编辑、删除或创建新用户。
在创建新用户或删除用户的情况下,当导航回 UserListView 屏幕时,会实例化一个新的 UserListViewModel,它会重新调用数据库以获取刚刚所做的更改。
问题是视图不反映 ViewModel 的状态。就像应用程序从第一次实例化时开始缓存视图一样。
例如,如果在 UserListView 中,我单击添加新用户按钮,转到 UserDetailView,添加新用户的详细信息,单击保存,然后导航回 UserListView - 新创建的用户不在视图中。
请注意,我已经调试过了,可以确认 ViewModel 有正确的数据。我正在使用 MVVM Light 和 Fody 来处理INotifyPropertyChanged。
这与视图的缓存有关吗?我已经尝试添加 Mode=TwoWay 来绑定 DataTemplates 和 ContentControl 的绑定,但没有成功。
我做了一个测试,我在 UserListView 上有一个删除按钮,该按钮经过硬编码以从数据库中删除特定用户,然后刷新绑定到视图中表的数据库中的用户列表 - 这工作正常,行消失。所以这似乎是一个缓存问题。
请注意,我没有为 UserListView 和 UserDetailView 及其 ViewModel 提供代码片段,因为我认为这不相关。
MainViewModel.xaml
<Window x:Class="WPFApp.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:WPFApp"
xmlns:vm="clr-namespace:App.Logic;assembly=WPFApp"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd1="http://www.galasoft.ch/mvvmlight"
mc:Ignorable="d"
Title="WPF App" WindowState="Maximized"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ResourceDictionary>
<DataTemplate DataType="{x:Type vm:UserListViewModel}">
<local:UserListView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:UserDetailViewModel}">
<local:UserDetailView/>
</DataTemplate>
</ResourceDictionary>
</Window.Resources>
<DockPanel>
<ContentControl Content="{Binding SelectedViewModel}"></ContentControl>
</DockPanel>
主视图模型.cs
public class MainViewModel : ViewModelBase
{
public event PropertyChangedEventHandler PropertyChanged;
public object SelectedViewModel { get; set; }
public MainViewModel()
{
SelectedViewModel = new HomeViewModel();
}
public RelayCommand HomeNavigationCommand => new RelayCommand(HomeNavigate);
private void HomeNavigate() => Navigate(new HomeViewModel());
public RelayCommand UserListNavigationCommand => new RelayCommand(UserListNavigate);
private void UserListNavigate() => Navigate(new UserListViewModel());
private void UserDetailNavigate(UserDetailUserMessage user) => Navigate(new UserDetailViewModel(user));
private void Navigate(object viewModel)
{
SelectedViewModel = viewModel;
}
}