代码中的WPF命令后面没有触发

时间:2017-05-22 09:16:47

标签: c# wpf xaml mvvm command

我正在使用 MVVM 模式开发 WPF 应用程序,我仍然是.NET开发的新手。我的理解是视图应将其数据上下文设置为 ViewModel ,然后任何与数据相关的处理应在 ViewModel 中完成,而<应在视图中处理strong> UI 部分( XAML 代码隐藏)。

所以我有一个菜单,每个菜单项都绑定到 DelegateCommand (使用 Prism ),并使用键盘快捷键在 ViewModel 中声明和处理它完美无瑕。但是,我想将绑定一个菜单项添加到 View的代码隐藏文件中的命令,因为它不会删除任何数据(它只是显示或隐藏面板)。

查看(XAML)

<Window x:Class="Editor.Views.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:Editor.Views"
        xmlns:vm="clr-namespace:Editor.ViewModels"
        mc:Ignorable="d"
        x:Name="RootWindow"
        WindowStartupLocation="CenterScreen"
        Width="1200" Height="650">

    <!-- Data Context -->
    <Window.DataContext>
        <vm:MainViewModel />
    </Window.DataContext>

    <!-- Keyboard Shortcuts -->
    <Window.InputBindings>
        <KeyBinding Modifiers="Control" Key="L" Command="{Binding ElementName=RootWindow, Path=ToggleLayersCommand}" />
    </Window.InputBindings>

    <!-- Main Menu -->
    <Menu>
        <MenuItem Header="View" Padding="5, 2">
            <MenuItem Header="Toggle Layers Panel" InputGestureText="CTRL + L" Command="{Binding ElementName=RootWindow, Path=ToggleLayersCommand}" />
        </MenuItem>
    </Menu>

</Window>

查看(代码隐藏)

public partial class MainWindow : Window
{
    public DelegateCommand ToggleLayersCommand { get; private set; }

    public MainWindow()
    {
        InitializeComponent();
        ToggleLayersCommand = new DelegateCommand(ToggleLayersCommand_OnExecuted, () => true);
    }

    private void ToggleLayersCommand_OnExecuted()
    {
        LayerListPanel.Visibility = (LayerListPanel.Visibility == Visibility.Collapsed) ? Visibility.Visible : Visibility.Collapsed;
    }
}

我在XAML中命名窗口,在绑定命令属性<时,在查看而不是 ViewModel 中找到命令 / strong>即可。它似乎找到它,因为我得到 intellisense ,但它永远不会发射。

我可以使用点击事件,即使我宁愿使用命令但是如何绑定 键盘快捷方式事件

3 个答案:

答案 0 :(得分:0)

您必须使用ViewModel命令,而不是View

视图模型:

public partial class MainViewModel
{
    public DelegateCommand ToggleLayersCommand { get; private set; }

    public MainViewModel()
    {
        ToggleLayersCommand = new DelegateCommand(ToggleLayersCommand_OnExecuted, () => true);
    }

    private void ToggleLayersCommand_OnExecuted()
    {
        LayerListPanel.Visibility = (LayerListPanel.Visibility == Visibility.Collapsed) ? Visibility.Visible : Visibility.Collapsed; 
//THIS WILL PROBABLY NOT WORK...
//You can use another public property to change your visibility.
// Create a public visibility and bind it to the correct item
    }
 }

XAML:

<Menu>
    <MenuItem Header="View" Padding="5, 2">
       <MenuItem Header="Toggle Layers Panel" InputGestureText="CTRL + L" Command="{Binding Path=ToggleLayersCommand}" />
        </MenuItem>
 </Menu>

答案 1 :(得分:0)

我将在ViewModel中定义命令并让它更改属性public Visibility LayerListPanelVisibility(也应该在ViewModel中定义)。然后我会将LayerListPanel.Visibility绑定到此属性。

尽可能保持代码隐藏。

绑定未找到命令的原因是,解析绑定时ToggleLayersCommandnull。只有在绑定解析后不久,您才能将正确的命令分配给ToggleLayersCommand。但是,由于Viewmodel不会引发PropertyChanged事件,因此不会更新Binding。

如果要将命令保留在视图中,可以在分配命令时引发PropertyChanged事件,也可以在调用InitializeComponent之前分配命令:

public MainWindow()
{
    ToggleLayersCommand = new DelegateCommand(ToggleLayersCommand_OnExecuted, () => true);
    InitializeComponent();
}

答案 2 :(得分:0)

我遇到绑定命令到键绑定的同样问题。我所做的就是给一个按钮一个自己的名字,并从set命令后面的视图代码给你。

我的例子如下:

<KeyBinding x:Name="ShowDetailsKeyBinding"
                Key="D"
                Modifiers="Control" />

代码背后:

ShowDetailsKeyBinding.Command = new DelegateCommand(ShowDetailsOperation);

我使用此解决方案来运行我的动画,其他方式你应该在你的ViewModel中创建命令。