【问题标题】:Dynamic menus and submenus with Caliburn Micro, how can I bind the commands?Caliburn Micro 的动态菜单和子菜单,如何绑定命令?
【发布时间】:2020-05-27 15:14:47
【问题描述】:

我在 WPF 项目中使用 Caliburn Micro,我希望插件组件能够填充工具栏。每个插件都有一个顶级菜单项,如果他们愿意,可以用子菜单填充它。

<ToolBar>
    <Menu x:Name="ToolBarMenuItems">
        <Menu.ItemContainerStyle>
            <Style TargetType="{x:Type MenuItem}">
                <Setter Property="Header" Value="{Binding Path=Text}" />
                <Setter Property="ItemsSource" Value="{Binding Path=Children}" />
            </Style>
        </Menu.ItemContainerStyle>
    </Menu>
</ToolBar>

ToolBarMenuItems 是一个接口的 BindableCollection:

public BindableCollection<IMenuItemViewModel> ToolBarMenuItems { get; set; }

public interface IMenuItemViewModel
{
    string Text { get; set; }

    ObservableCollection<IMenuItemViewModel> Children { get; set; }

    bool CanRunCommand();

    void RunCommand();
}

就创建菜单而言,这可以正常工作,问题是将菜单项连接到 RunCommand/CanRunCommand。 Dynamic menus with Caliburn micro 解释了如何在 MenuItem 上执行此操作:

<Menu>
    <MenuItem x:Name="ToolBarMenuItems" DisplayMemberPath="Text" Header="MyMenu" cal:Message.Attach="RunToolbarCommand($originalsourcecontext)"/>
</Menu>

其中 RunToolBarCommand 是视图模型public void RunToolbarCommand(IMenuItemViewModel menuItem) 中的一个方法,$originalsourcecontext 是指在引导程序中设置以下内容

MessageBinder.SpecialValues.Add("$originalsourcecontext", context =>
{
    var args = context.EventArgs as RoutedEventArgs;
    var fe = args?.OriginalSource as FrameworkElement;
    return fe?.DataContext;
});

但正如我所说,我需要为整个菜单执行此操作,而不仅仅是在 MenuItem 上,但我不知道如何使用 Caliburn Micro 来绑定方法。

【问题讨论】:

  • 我不明白你的问题,你能详细说明一下吗?您有一个可用于 menuitem 的提示,但是您的绑定方法问题在哪里?显示你想要的样本..对不起我的英语
  • 基本上我的工作示例是一个 MenuItem,其中列表中的每个对象都是一个子菜单项。如果我有标准菜单,如文件、编辑、插件等。这将是完美的,我会把它放在插件菜单项上,每个插件都会有一个子菜单来玩。我不希望它出现在 MenuItem 上,我希望它出现在 Menu 上,并且集合中的每个对象都应该是该 Menu 上的顶级 MenuItem。这是因为我想要一个工具栏,其中每个插件都有一个顶级 MenuItem,如果需要,它可以在其中添加子菜单。
  • 我添加了一张图片来澄清。

标签: c# wpf caliburn.micro commandbinding


【解决方案1】:

向您的Style 添加一个设置器,设置cal:Message.Attach 附加属性并传递$executionContext

<Menu x:Name="ToolBarMenuItems">
    <Menu.ItemContainerStyle>
        <Style TargetType="{x:Type MenuItem}">
            <Setter Property="Header" Value="{Binding Path=Text}" />
            <Setter Property="ItemsSource" Value="{Binding Path=Children}" />
            <Setter Property="cal:Message.Attach" Value="RunCommand($executionContext)" />
        </Style>
    </Menu.ItemContainerStyle>
</Menu>

您需要界面和实现中的上下文才能阻止事件冒泡:

public void RunCommand(ActionExecutionContext context)
{
    if (context?.EventArgs is RoutedEventArgs routedEventArgs)
        routedEventArgs.Handled = true;

    MessageBox.Show("Run!");
}

请参阅this问题了解更多信息。

【讨论】:

  • 完美运行,非常感谢!我没有意识到 cal:Message.Attatch 可以用作样式的属性,尽管现在我看到它似乎很明显(通常是这种情况)。
猜你喜欢
  • 1970-01-01
  • 2015-04-28
  • 2016-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
相关资源
最近更新 更多