我在一个窗口中有一个两行网格。在第一行有一个带有按钮的堆栈面板。单击一个按钮会在网格的第二行显示一个用户控件。(我得到了该部分的工作)。现在在用户控件内部有多个按钮应该更改网格第二行的内容(将当前用户控件更改为另一个)。
当我单击客户用户控件中的按钮并将断点放置到 BaseViewModel 中的 NavigationCommand 时,它实际上会更改 CurrentViewModel 但不会出现在实际窗口中。
MainWindow.xaml
<Window x:Class="TestProject.View.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:viewmodel="clr-namespace:TestProject.ViewModel"
xmlns:local="clr-namespace:TestProject"
xmlns:view="clr-namespace:TestProject.View"
mc:Ignorable="d"
Title="MainWindow" Width="966" Height="897">
<Window.DataContext>
<viewmodel:MainWindowViewModel/>
</Window.DataContext>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<!--Верхнее меню -->
<Grid Grid.Row="0">
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal" >
<Button x:Name="Visits" Background="Transparent" Command="{Binding NavigationCommand}" CommandParameter="visits" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0">
<Image Source="../icon/document-changed.png" Width="16" Height="16"/>
</Button>
<Button x:Name="Patients" Background="Transparent" Command="{Binding NavigationCommand}" CommandParameter="patients" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0">
<Image Source="../icon/document-changed.png" Width="16" Height="16"/>
</Button>
<Button x:Name="Customers" Background="Transparent" Command="{Binding NavigationCommand}" CommandParameter="customers" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0">
<Image Source="../icon/user.png" Width="16" Height="16"/>
</Button>
<Button x:Name="Goods" Background="Transparent" Command="{Binding NavigationCommand}" CommandParameter="customer" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0">
<Image Source="../icon/folder_documents.png" Width="16" Height="16"/>
</Button>
<Button x:Name="Services" Background="Transparent" Command="{Binding NavigationCommand}" CommandParameter="services" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0">
<Image Source="../icon/folder_documents.png" Width="16" Height="16"/>
</Button>
</StackPanel>
</Grid>
<ContentControl x:Name="Content" Grid.Row="1" Content="{Binding CurrentViewModel}"></ContentControl>
</Grid>
</Window>
BaseViewModel
namespace TestProject.ViewModel
{
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public DelegateCommand<string> NavigationCommand { get; set; }
public BaseViewModel()
{
NavigationCommand = new DelegateCommand<string>(OnNavigate);
}
private void OnNavigate(string navPath)
{
switch (navPath)
{
case "customers":
CurrentViewModel = new CustomersViewModel();
break;
case "visits":
CurrentViewModel = new VisitsViewModel();
break;
case "patients":
CurrentViewModel = new PatientsViewModel();
break;
case "customer":
CurrentViewModel = new CustomerViewModel();
break;
case "visit":
CurrentViewModel = new VisitViewModel();
break;
}
}
private object _currentViewModel;
public object CurrentViewModel
{
get { return _currentViewModel; }
set
{
if (_currentViewModel != value)
{
_currentViewModel = value;
OnPropertyChanged();
}
}
}
private object _currentText;
public object CurrentText
{
get { return _currentText; }
set
{
if (_currentText != value)
{
_currentText = value;
OnPropertyChanged();
}
}
}
}
}
客户.xaml
<UserControl x:Class="TestProject.View.Customers"
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:TestProject.View"
xmlns:viewModel="clr-namespace:TestProject.ViewModel"
mc:Ignorable="d"
>
<UserControl.DataContext>
<viewModel:CustomersViewModel/>
</UserControl.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" Background="#FFF3EB96">Клиенты</Label>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Button Command="{Binding NavigationCommand}" CommandParameter="customer" Background="Transparent" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0">
<StackPanel Orientation="Horizontal">
<Image Source="../icon/plus_32.png" Width="32" Height="32"/>
</StackPanel>
</Button>
</StackPanel>
</Grid>
</UserControl>
最佳答案
您似乎已经定义了 CurrentViewModel
所有 View 模型的公共(public)基类中的属性。这是错误的。ContentControl
在 View 中绑定(bind)到 View 模型类的特定实例,因此设置 CurrentViewModel
CustomersViewModel
的属性(property)不会影响 ContentControl
绑定(bind)到 CurrentViewModel
MainWindowViewModel
的属性(property).CustomersViewModel
应该直接引用 MainWindowViewModel
,否则您将不得不使用某种信使/事件聚合器或共享服务在它们之间进行通信:https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/ .
如果您通过引用 MainWindowViewModel
注入(inject) subview 模型创建它们时,您可以使用此引用进行导航:
主窗口 View 模型:
public class MainWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public DelegateCommand<string> NavigationCommand { get; set; }
public BaseViewModel()
{
NavigationCommand = new DelegateCommand<string>(OnNavigate);
}
private void OnNavigate(string navPath)
{
switch (navPath)
{
case "customers":
CurrentViewModel = new CustomersViewModel(this);
break;
...
}
}
客户查看型号:
public class CustomersViewModel
{
private readonly MainWindowViewModel _vm;
public CustomersViewModel(MainWindowViewModel vm)
{
_vm = vm;
NavigationCommand = new DelegateCommand<string>(OnNavigate);
}
public DelegateCommand<string> NavigationCommand { get; set; }
private void OnNavigate(string navPath)
{
_vm.CurrentViewModel = new SomeOtherViewModel();
}
}
关于c# - 在用户控件内单击按钮更改 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45140890/