在用户控件内单击按钮的查看视图

时间:2017-07-17 09:45:37

标签: c# wpf xaml mvvm

我在窗口内有一个双行网格。在第一行中,有一个带按钮的堆栈面板。单击按钮会在网格的第二行显示用户控件。(我使该部分工作)。现在在用户控件内部有多个按钮,它应该改变网格第二行的内容(将当前用户控件更改为另一个)。 当我单击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>

1 个答案:

答案 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;
            ...
        }
    }