我在窗口内有一个双行网格。在第一行中,有一个带按钮的堆栈面板。单击按钮会在网格的第二行显示用户控件。(我使该部分工作)。现在在用户控件内部有多个按钮,它应该改变网格第二行的内容(将当前用户控件更改为另一个)。 当我单击Customers用户控件中的一个按钮并在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();
}
}
}
}
}
Customers.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>
答案 0 :(得分:0)
您似乎已在所有视图模型的公共基类中定义了CurrentViewModel
属性。这是错的。
视图中的ContentControl
绑定到视图模型类的特定实例,因此设置CurrentViewModel
CustomersViewModel
属性不会影响ContentControl
绑定到CurrentViewModel
的{{1}}属性。
MainWindowViewModel
应该直接引用CustomersViewModel
,或者您必须使用某种信使/事件聚合器或共享服务在它们之间进行交流:https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/。< / p>
如果您在创建子视图模型时引用了MainWindowViewModel
的引用,则可以使用此引用进行导航:
<强> MainWindowViewModel:强>
MainWindowViewModel
<强> CustomersViewModel:强>
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;
...
}
}