首页 > 解决方案 > 如何在用户控件中使用命令

问题描述

我正在尝试使用我创建的命令。我正在为我的应用程序使用 c# 和 MVVM 结构。我有 1 个窗口(ApplicationView),用于显示我的 userContols(MainWindow,Window1)。在启动时,我显示了 MainWindow 用户控件,并且该用户控件上有一个按钮,当您按下该按钮时,会将用户控件从主窗口 usercontol 更改为 Window1 userContol。

ApplicationView.xaml(窗口)

<Window x:Class="Nmenq.ApplicationView"
    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:Nmenq"
    xmlns:my="clr-namespace:Nmenq"
    Title="ApplicationView" Height="400" Width="575">

<Window.Resources>
    <DataTemplate DataType="{x:Type local:MainWindowViewModel}">
        <local:MainWindow/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:Window1ViewModel}">
        <local:Window1/>
    </DataTemplate>
</Window.Resources>
<DockPanel LastChildFill="True">
    <ContentControl x:Name="Pages" DockPanel.Dock="Right" Content="{Binding CurrentPageViewModel}"/>
</DockPanel>

应用程序视图.xaml.cs

public partial class ApplicationView : Window
{
    public ApplicationView()
    {
        InitializeComponent();
        this.DataContext = new NavigationViewModel();
    }
}

MainWindow.xaml(用户控件)

<UserControl x:Class="Nmenq.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:Nmenq"
    xmlns:viewmodel="clr-namespace:Nmenq.ViewModel"
    xmlns:my="clr-namespace:Nmenq"
    mc:Ignorable="d"
    d:DesignHeight="400" d:DesignWidth="575">


<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}">
    <Button x:Name="Accept_Button" Content="Accept" HorizontalAlignment="Left" Margin="475,316,0,0" VerticalAlignment="Top" Width="81" Command="{Binding Window1Command}"/>   
</Grid>

主窗口.xmal.cs

    public partial class MainWindow : UserControl, INotifyPropertyChanged
{

    NavigationViewModel object1 = new NavigationViewModel();

    public ICommand Window1Command { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        Window1Command = object1.Window1Command;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}

NavigationViewModel(我的命令设置在哪里)

    class NavigationViewModel : INotifyPropertyChanged
{
    public ICommand MainWindowCommand { get; set; }
    public ICommand Window1Command { get; set; }

    private object currentPageViewModel;
    public object CurrentPageViewModel
    {
        get { return currentPageViewModel; }
        set { currentPageViewModel = value; OnPropertyChanged("CurrentPageViewModel"); }
    }

    public NavigationViewModel()
    {
        MainWindowCommand = new BaseCommand(OpenMainWindow);
        Window1Command = new BaseCommand(OpenWindow1);

        CurrentPageViewModel = new MainWindowViewModel();

    }

    public void OpenMainWindow(object obj)
    {
        CurrentPageViewModel = new MainWindowViewModel();
    }

    public void OpenWindow1(object obj)
    {
        CurrentPageViewModel = new Window1ViewModel();

    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
}

public class BaseCommand : ICommand
{
    private Predicate<object> _canExecute;
    private Action<object> _method;
    public event EventHandler CanExecuteChanged;

    public BaseCommand(Action<object> method)
        : this(method, null)
    {
    }

    public BaseCommand(Action<object> method, Predicate<object> canExecute)
    {
        _method = method;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        if (_canExecute == null)
        {
            return true;
        }

        return _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _method.Invoke(parameter);
    }
}    class NavigationViewModel : INotifyPropertyChanged
{
    public ICommand MainWindowCommand { get; set; }
    public ICommand Window1Command { get; set; }

    private object currentPageViewModel;
    public object CurrentPageViewModel
    {
        get { return currentPageViewModel; }
        set { currentPageViewModel = value; OnPropertyChanged("CurrentPageViewModel"); }
    }

    public NavigationViewModel()
    {
        Window1Command = new BaseCommand(OpenWindow1);

        CurrentPageViewModel = new MainWindowViewModel();

    }

    public void OpenWindow1(object obj)
    {
        CurrentPageViewModel = new Window1ViewModel();

    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
}

public class BaseCommand : ICommand
{
    private Predicate<object> _canExecute;
    private Action<object> _method;
    public event EventHandler CanExecuteChanged;

    public BaseCommand(Action<object> method)
        : this(method, null)
    {
    }

    public BaseCommand(Action<object> method, Predicate<object> canExecute)
    {
        _method = method;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        if (_canExecute == null)
        {
            return true;
        }

        return _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _method.Invoke(parameter);
    }
}

任何帮助或建议将不胜感激:)

标签: c#wpfmvvm

解决方案


您可以直接绑定到 的Window1Command属性NavigationViewModel并从 中删除该Window1Command属性UserControl

<Button x:Name="Accept_Button" Content="Accept" HorizontalAlignment="Left" Margin="475,316,0,0" VerticalAlignment="Top" Width="81" 
        Command="{Binding DataContext.Window1Command, RelativeSource={RelativeSource AncestorType=Window}}"/>

推荐阅读