我正在使用 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 ,但它永远不会发射。
我可以使用点击事件,即使我宁愿使用命令但是如何绑定 键盘快捷方式到事件?
答案 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
绑定到此属性。
尽可能保持代码隐藏。
绑定未找到命令的原因是,解析绑定时ToggleLayersCommand
为null
。只有在绑定解析后不久,您才能将正确的命令分配给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中创建命令。