You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于WPF与Mahapps.Metro实现汉堡菜单(适配Caliburn.Micro)

把Caliburn.Micro导航逻辑迁移到HamburgerMenu的解决方案

我之前也遇到过类似的问题——因为HamburgerMenuGlyphItem并非FrameworkElement,Caliburn.Micro的Message.Attach无法直接在它上面生效。结合你已经实现的视图切换逻辑,这里有两种实用的方案帮你完成迁移:

方法1:通过ItemClick事件统一处理(快速复用现有代码)

这种方式不需要改动你现有的ViewModel方法,只需要给HamburgerMenu绑定ItemClick事件,通过Tag标识对应操作:

XAML代码

<Controls:HamburgerMenu cal:Message.Attach="[Event ItemClick] = [HandleNavigation($eventArgs)]">
    <Controls:HamburgerMenu.ItemTemplate>
        <DataTemplate DataType="{x:Type Controls:HamburgerMenuGlyphItem}">
            <Grid Height="48">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="48" />
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <!-- 这里用Segoe MDL2 Assets的图标,替换成你需要的Glyph值 -->
                <TextBlock Margin="12" 
                           HorizontalAlignment="Center" 
                           VerticalAlignment="Center" 
                           Text="{Binding Glyph}" 
                           FontFamily="Segoe MDL2 Assets"/>
                <TextBlock Grid.Column="1" 
                           VerticalAlignment="Center" 
                           FontSize="16" 
                           Text="{Binding Label}" />
            </Grid>
        </DataTemplate>
    </Controls:HamburgerMenu.ItemTemplate>
    <Controls:HamburgerMenu.ItemsSource>
        <Controls:HamburgerMenuItemCollection>
            <Controls:HamburgerMenuGlyphItem Glyph="&#xE700;" Label="Main Menu" Tag="ShowMainMenu"/>
            <Controls:HamburgerMenuGlyphItem Glyph="&#xE894;" Label="Reports" Tag="ShowReportsMenu"/>
            <Controls:HamburgerMenuGlyphItem Glyph="&#xE729;" Label="Reset" Tag="Reset"/>
            <Controls:HamburgerMenuGlyphItem Glyph="&#xE71A;" Label="Close" Tag="TryClose"/>
        </Controls:HamburgerMenuItemCollection>
    </Controls:HamburgerMenu.ItemsSource>
</Controls:HamburgerMenu>

ViewModel代码

在你的主ViewModel里添加事件处理方法,根据Tag调用你已实现的导航方法:

using Microsoft.UI.Xaml.Controls; // 或者对应你用的HamburgerMenu所在的命名空间

public void HandleNavigation(ItemClickEventArgs e)
{
    if (e.ClickedItem is HamburgerMenuGlyphItem selectedItem && selectedItem.Tag is string actionName)
    {
        switch (actionName)
        {
            case "ShowMainMenu":
                ShowMainMenu(); // 你的现有方法
                break;
            case "ShowReportsMenu":
                ShowReportsMenu(); // 你的现有方法
                break;
            case "Reset":
                Reset(); // 你的现有方法
                break;
            case "TryClose":
                TryClose(); // 你的现有方法
                break;
        }
    }
}

方法2:自定义导航项ViewModel(更符合MVVM风格)

这种方式把每个导航项封装成ViewModel,直接绑定命令,更贴合Caliburn.Micro的设计思想:

1. 创建导航项模型类

using System.Windows.Input;
using Caliburn.Micro;

public class NavigationItem
{
    public string Glyph { get; set; }
    public string Label { get; set; }
    public ICommand Command { get; set; }
}

2. 更新主ViewModel

把导航项集合绑定到HamburgerMenu,同时关联你已有的方法:

public BindableCollection<NavigationItem> NavigationItems { get; set; }

public MainViewModel()
{
    NavigationItems = new BindableCollection<NavigationItem>
    {
        new NavigationItem 
        { 
            Glyph = "&#xE700;", 
            Label = "Main Menu", 
            Command = new DelegateCommand(ShowMainMenu) 
        },
        new NavigationItem 
        { 
            Glyph = "&#xE894;", 
            Label = "Reports", 
            Command = new DelegateCommand(ShowReportsMenu) 
        },
        new NavigationItem 
        { 
            Glyph = "&#xE729;", 
            Label = "Reset", 
            Command = new DelegateCommand(Reset) 
        },
        new NavigationItem 
        { 
            Glyph = "&#xE71A;", 
            Label = "Close", 
            Command = new DelegateCommand(TryClose) 
        }
    };
}

// 你的现有导航方法
public void ShowMainMenu() { /* 已实现的视图切换逻辑 */ }
public void ShowReportsMenu() { /* 已实现的视图切换逻辑 */ }
public void Reset() { /* 已实现的重置逻辑 */ }
public void TryClose() { /* 已实现的关闭逻辑 */ }

3. 修改XAML

用Button作为项的容器(添加透明样式避免默认按钮视觉效果),直接绑定命令:

<Controls:HamburgerMenu ItemsSource="{Binding NavigationItems}">
    <Controls:HamburgerMenu.Resources>
        <Style x:Key="TransparentHamburgerItemButton" TargetType="Button">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Padding" Value="0"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Controls:HamburgerMenu.Resources>
    
    <Controls:HamburgerMenu.ItemTemplate>
        <DataTemplate>
            <Button Height="48" 
                    Command="{Binding Command}"
                    Style="{StaticResource TransparentHamburgerItemButton}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="48" />
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Margin="12" 
                               HorizontalAlignment="Center" 
                               VerticalAlignment="Center" 
                               Text="{Binding Glyph}" 
                               FontFamily="Segoe MDL2 Assets"/>
                    <TextBlock Grid.Column="1" 
                               VerticalAlignment="Center" 
                               FontSize="16" 
                               Text="{Binding Label}" />
                </Grid>
            </Button>
        </DataTemplate>
    </Controls:HamburgerMenu.ItemTemplate>
</Controls:HamburgerMenu>

补充说明

Caliburn.Micro确实没有针对第三方HamburgerMenu控件的官方文档,核心思路就是利用Caliburn的事件绑定(Message.Attach)或者命令绑定能力,把控件的交互和ViewModel的逻辑关联起来。两种方案都可以完美适配你已有的视图切换功能,按需选择即可。

内容的提问来源于stack exchange,提问作者Sabyasachi Mukherjee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:51:16