2017-05-22 43 views
1

我正在使用MVVM模式的WPF应用程序,我对.NET开发还很新。我的理解是,查看应的数据上下文设置为视图模型,然后任何数据相关的处理应在视图模型来完成,而UI部分应该在视图中处理(XAML代码在之后)。WPF命令在代码后面不被触发

所以我有一个绑定到一个DelegateCommand(使用棱镜)每个菜单项的菜单声明,并在视图模型与键盘快捷键处理,它完美的作品。然而,我想绑定一个菜单项到命令查看代码后面文件,因为它不manupulate任何数据(它只是显示或隐藏面板)。

视图(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当绑定命令属性。它似乎找到它,因为我得到intellisense但它永远不会燃烧。

我可以用一个click事件,而不是即使我宁愿使用一个命令但再怎么绑定键盘快捷键事件

回答

0

我将定义视图模型里面的命令,并把它更改属性public Visibility LayerListPanelVisibility(它也应该在ViewModel中定义)。然后我会将LayerListPanel.Visibility绑定到此属性。

保持您的代码隐藏尽可能空。


该命令不被你的绑定发现的原因是ToggleLayersCommandnull当绑定解决。只有在绑定解析后,您才能将正确的命令分配给ToggleLayersCommand。但是,绑定不会更新,因为您的Viewmodel不会引发PropertyChanged事件。

如果你想保持你的命令,在视图中,你可以提出一个PropertyChanged事件如果您已指定命令,或者你打电话InitializeComponent之前分配命令:

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

所以,即使它与数据无关,它可以放在ViewModel中吗? – BronanyX

+0

它是逻辑控制视图。这正是ViewModel应该是的。 – wkl

+0

嗯,我认为我现在有一个更好的理解,是在InitializeComponent工作之前绑定命令,但我想我将它移动到ViewModel。 – BronanyX

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> 
0

我有同样的问题绑定命令到键绑定。我所做的一切都是给自己的名字和设置命令背后的视图代码给你一个按钮。

我的例子看起来像这样:

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

后面的代码:

ShowDetailsKeyBinding.Command = new DelegateCommand(ShowDetailsOperation); 

我用这个解决方案来运行我的动画,你应该建立在你的ViewModel命令其他方式。