通过 MVVM 绑定菜单项的命令

本文关键字:命令 菜单项 绑定 MVVM 通过 | 更新日期: 2023-09-27 17:56:17

>我设置了一个系统,其中使用 MVVM 架构动态填充 ContextMenu 层次结构。除命令外,我的所有绑定都正常运行。我的视图是一个指定 ItemContainerStyle 的上下文菜单。

ContextMenu 的 ItemContainerStyle 设置为:

<ContextMenu.ItemContainerStyle>
    <Style TargetType="MenuItem">
        <Setter Property="Command" Value="{Binding Command, Mode=OneWay}"/>
        <Setter Property="IsCheckable" Value="{Binding IsCheckable}"/>
        <Setter Property="IsChecked" Value="{Binding IsChecked, Mode=TwoWay}"/>
        <Setter Property="Header" Value="{Binding Label}"/>
        <Setter Property="ItemsSource" Value="{Binding Children}"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsVisible}" Value="False">
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</ContextMenu.ItemContainerStyle>

到目前为止,还没有 ItemTemplate,因为似乎我已经能够在样式中完成所有所需的功能。

ViewModel 必须使用它包装的模型的实例来构造,因此似乎 ContextMenu 的 DataContext 无法显式设置为 ViewModel(编译器抱怨它没有无参数构造函数。投诉提到也可以使用类型转换器,尽管我不确定这实际上意味着什么(可以解决问题)。

我的 ViewModel 的相关部分如下,从以下两个可绑定到的只读面向公众的成员开始:

public CommandBinding CommandBinding { get; private set; }
public RoutedCommand Command { get { return CommandBinding.Command as RoutedCommand; } }
命令

绑定及其命令在构造函数中实例化:

CommandBinding = new CommandBinding(new RoutedCommand(), CommandBinding_Executed, CommandBinding_CanExecute);

该构造中引用的方法仅对模型的成员进行操作,并按如下方式实现:

void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    if (ContextItem.Command != null) ContextItem.Command(ContextItem);
}
void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = ContextItem.IsEnabled;
    if (ContextItem.ExecuteConditions != null) e.CanExecute = ContextItem.ExecuteConditions.GetInvocationList().Cast<ExecuteCondition>().All(s => s() == true);
}

似乎当绑定到命令实际工作时,所有项目都显示为灰色,就好像 CanExecute 返回 false 一样。但是,当我在 CanExecute 中设置断点时,执行永远不会在该点中断(尽管这可能是由于布局线程?即使我明确地将 e.CanExecute 设置为 true 并注释掉CommandBinding_CanExecute中的其他行,这些项目仍然显示为灰色。在 XAML 中,我尝试绑定到具有和不使用 Path= 的 Command 和 CommandBinding 成员,所有这些都达到了相同的效果。当我将绑定模式设置为 OneWayToSource 时,调试器会适当地抱怨该属性是只读的,无法对其进行操作(我希望 ViewModel 提供命令,因此这是有意的)。

我已经阅读了相关问题的其他示例和解决方案。对于那些遵循 MVVM 模式的用户,我无法确定我的实现有何不同。

对于任何解决方案,我必须坚持认为,我仍然可以要求使用模型作为参数构造 ViewModel,并且我希望视图保留所有 XAML,没有 C# 代码。

通过 MVVM 绑定菜单项的命令

似乎命令

绑定是问题所在。我最终创建了自己的 ICommand 实现,它允许我在构造上指定执行和可以执行委托......效果很好。

这解决了问题,实现很简单,但我仍然不清楚为什么我对命令绑定的使用不起作用。