C#实现左侧折叠导航菜单

基于C#实现左侧折叠导航菜单的完整技术方案,涵盖WinForms和WPF两种主流开发框架,结合界面设计、交互逻辑和工程实践:


一、WinForms实现方案

1. 基础控件组合

核心控件选择

  • Panel容器:用于包裹折叠内容
  • Button/Label:作为菜单触发器
  • TreeView:展示多级菜单结构
  • SplitContainer:实现左右分栏布局

示例代码

csharp 复制代码
// 初始化菜单面板
Panel menuPanel = new Panel {
    Dock = DockStyle.Left,
    Width = 200,
    BackColor = Color.FromArgb(240, 240, 240)
};

// 创建折叠按钮
Button toggleBtn = new Button {
    Text = "☰ 菜单",
    Dock = DockStyle.Top,
    Font = new Font("微软雅黑", 10, FontStyle.Bold),
    BackColor = Color.DimGray
};
toggleBtn.Click += (s, e) => {
    menuPanel.Width = menuPanel.Width == 200 ? 60 : 200;
    this.Invalidate(); // 触发重绘
};

// 添加到窗体
this.Controls.Add(toggleBtn);
this.Controls.Add(menuPanel);
2. 动画效果实现

通过定时器实现平滑展开/折叠:

csharp 复制代码
Timer aniTimer = new Timer { Interval = 20 };
int targetWidth = 200;
int currentWidth = 60;

void AnimateResize() {
    if (menuPanel.Width < targetWidth) {
        menuPanel.Width += 5;
        toggleBtn.Text = "☰ 菜单";
    } else if (menuPanel.Width > currentWidth) {
        menuPanel.Width -= 5;
        toggleBtn.Text = "▶ 内容";
    } else {
        aniTimer.Stop();
    }
}

// 触发时启动动画
toggleBtn.Click += (s, e) => {
    targetWidth = menuPanel.Width == 200 ? 60 : 200;
    currentWidth = menuPanel.Width;
    aniTimer.Start();
};
3. 多级菜单实现

使用TreeView控件构建层级结构:

csharp 复制代码
TreeNode node1 = new TreeNode("系统管理", 0, 0);
TreeNode node1_1 = new TreeNode("用户管理", 1, 1);
TreeNode node1_2 = new TreeNode("权限设置", 2, 2);
node1.Nodes.Add(node1_1);
node1.Nodes.Add(node1_2);

treeView1.Nodes.Add(node1);
treeView1.ExpandAll();

二、WPF实现方案

1. XAML布局设计
xml 复制代码
<Window x:Class="FoldableMenu.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        Title="折叠导航菜单" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <!-- 左侧菜单 -->
        <DockPanel x:Name="MenuDock" Grid.Column="0" Width="200" Background="#2D2D30">
            <Button DockPanel.Dock="Top" 
                    Content="☰ 菜单" 
                    Foreground="White" 
                    FontSize="16"
                    Margin="5"
                    Click="ToggleMenu"/>
            
            <Expander Header="系统管理" IsExpanded="False">
                <Expander.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" 
                                   Foreground="LightBlue" 
                                   Margin="5"/>
                    </DataTemplate>
                </Expander.HeaderTemplate>
                <ListBox>
                    <ListBoxItem Content="用户管理"/>
                    <ListBoxItem Content="权限设置"/>
                </ListBox>
            </Expander>
        </DockPanel>

        <!-- 主内容区 -->
        <Grid Grid.Column="1">
            <TextBlock Text="主内容区域" 
                       FontSize="24" 
                       VerticalAlignment="Center" 
                       HorizontalAlignment="Center"/>
        </Grid>
    </Grid>
</Window>
2. 动态菜单绑定

通过ViewModel绑定数据:

csharp 复制代码
public class MenuModel : INotifyPropertyChanged {
    private bool _isExpanded;
    public bool IsExpanded {
        get => _isExpanded;
        set {
            _isExpanded = value;
            OnPropertyChanged(nameof(IsExpanded));
        }
    }
    
    // 实现INotifyPropertyChanged接口
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string prop) {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
    }
}

// XAML绑定
<Expander Header="系统管理" IsExpanded="{Binding IsExpanded}">
3. 动画效果实现

使用Storyboard实现折叠动画:

xml 复制代码
<Window.Resources>
    <Storyboard x:Key="CollapseAnim">
        <DoubleAnimation Storyboard.TargetName="MenuDock" 
                         Storyboard.TargetProperty="Width"
                         From="200" To="60" Duration="0:0:0.3"/>
    </Storyboard>
    
    <Storyboard x:Key="ExpandAnim">
        <DoubleAnimation Storyboard.TargetName="MenuDock" 
                         Storyboard.TargetProperty="Width"
                         From="60" To="200" Duration="0:0:0.3"/>
    </Storyboard>
</Window.Resources>

// 触发动画
private void ToggleMenu(object sender, RoutedEventArgs e) {
    Storyboard sb = (MenuDock.Width == 200) 
        ? (Storyboard)FindResource("CollapseAnim") 
        : (Storyboard)FindResource("ExpandAnim");
    sb.Begin(this);
}

参考代码 C#左侧折叠导航菜单 youwenfan.com/contentcsb/111938.html

三、进阶功能实现

1. 图标与样式定制
  • 图标集成 :使用Image控件或字体图标库(如FontAwesome)
  • 悬停效果 :通过Style.Triggers实现颜色变化
xml 复制代码
<Style TargetType="Button">
    <Setter Property="Background" Value="Transparent"/>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="#404040"/>
        </Trigger>
    </Style.Triggers>
</Style>
2. 状态持久化

使用ApplicationSettings保存展开状态:

csharp 复制代码
// 保存状态
Properties.Settings.Default.MenuWidth = menuDock.Width;
Properties.Settings.Default.Save();

// 恢复状态
menuDock.Width = Properties.Settings.Default.MenuWidth;
3. 多分辨率适配
  • WPF自适应布局 :使用Viewbox控件自动缩放
  • WinForms动态调整 :监听Resize事件
csharp 复制代码
private void Form_Resize(object sender, EventArgs e) {
    menuPanel.Width = this.ClientSize.Width / 4;
}

四、第三方库推荐

库名称 特点 适用场景
HslCommunication 提供现成的导航控件,支持主题切换 企业级应用开发
DevExpress WinForms 包含Ribbon控件和高级布局管理器 复杂业务系统
MaterialDesignInXaml 实现Material Design风格菜单 现代化UI设计

五、工程实践建议

  1. 模块化设计:将菜单项封装为独立UserControl
  2. 权限控制:通过角色标识动态加载菜单项
  3. 性能优化 :虚拟化技术处理大量菜单项(WPF的VirtualizingStackPanel
  4. 测试方案:
    • 多分辨率测试(1920x1080/1366x768等)
    • 快速点击防抖处理
    • 低配环境性能测试