C#WPF实战出真汁05--左侧导航

发布于:2025-08-16 ⋅ 阅读:(16) ⋅ 点赞:(0)

1、左侧导航设计要点

清晰的信息架构
确保导航结构层次分明,主分类与子分类逻辑清晰,避免过度嵌套。使用分组、缩进或分隔线区分不同层级,保持视觉可读性。

直观的图标与标签
为每个导航项搭配简洁的图标,强化视觉识别。标签文字需简短明确,避免专业术语,保证用户快速理解功能或内容。

响应式交互设计
悬停状态应有视觉反馈(如颜色变化、背景高亮)。当前选中项需突出显示(如底色、边框或文字加粗),帮助用户定位。可折叠菜单需支持平滑展开/收起动画。

视觉层次与留白
通过字体大小、颜色深浅或间距区分主次内容。保留充足留白,避免信息拥挤。暗色背景或分割线可提升导航区与主内容的区分度。

性能优化
动态加载子菜单减少初始加载时间。对于大型导航,提供搜索或快捷操作功能。确保导航在移动端可通过汉堡菜单调用,并适配触控操作。

无障碍适配
支持键盘导航(Tab键切换),提供ARIA标签说明。颜色对比度符合WCAG标准,图标需附带文字说明以兼容屏幕阅读器。

2、主窗体布局设计

主窗体布局设计需要考虑用户交互的便捷性和视觉舒适度。采用清晰的区域划分,确保功能模块易于访问。常见的布局方式包括单窗口、多文档界面(MDI)或标签式布局,具体选择取决于应用类型和功能复杂度。
保持一致的间距和对齐方式,避免元素拥挤或分散。使用网格系统辅助控件排列,确保界面整洁。重要功能或高频操作应放置在显眼位置,例如顶部工具栏或侧边栏。
常见布局模式
顶部导航+侧边栏+内容区
顶部放置应用标题和全局导航,左侧设置功能菜单或工具面板,中央区域作为主要内容展示区。这种模式适合功能较多的桌面应用,如设计软件或开发工具。
全屏内容+浮动面板
主窗口以内容展示为核心,辅助功能以可折叠面板形式出现。适合媒体编辑类软件,如视频剪辑或图像处理工具,能最大化工作区利用率。
卡片式平铺布局
将功能模块以等比例卡片形式平铺在主窗口,通过视觉层次区分优先级。适用于数据仪表盘或控制中心类应用,信息呈现直观清晰。

响应式设计要点
考虑窗口大小变化时的布局适应性。定义最小窗口尺寸限制,防止内容挤压变形。使用锚定(Anchoring)和停靠(Docking)技术确保控件随窗口缩放时保持相对位置。

为高分辨率屏幕提供多套尺寸方案,确保图标和文字在不同DPI设置下清晰可见。重要按钮和交互元素应设置在鼠标热区范围内,减少操作疲劳。

视觉层次构建
通过颜色对比、阴影效果或间距区分不同功能区块。主操作按钮使用强调色突出显示,次级功能采用中性色调。保持字体类型不超过三种,通过字号差异建立信息层级。

状态栏和提示信息使用低饱和度色彩,避免分散注意力。动态元素如进度条或通知标志需设计醒目但不过度干扰。

辅助功能考虑
为视力障碍用户提供高对比度模式选项,支持键盘快捷键操作所有功能。控件间Tab顺序需符合逻辑流,焦点状态应有明显视觉反馈。界面文字应支持动态缩放,避免固定像素单位。

布局设计如图:

左侧里面又定义了3行,每行放不同的内容,分别是图标,菜单,按钮,其中菜单通过TreeView控件实现,当点击不同treeitem时,呈现不同的内容显示在右侧,treeview控件点击事件由TvMenu_SelectionChanged事件来处理,样式由TreeView.ItemTemplate模板来定义,前面提到过国内优秀的WPF开源控件库,Panuon.UI.Silver,它能提供很好的样式,如图所示:

完整代码如下:

<pu:WindowX
    x:Class="HQ.fResApp.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:local="clr-namespace:HQ.fResApp"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:pu="clr-namespace:Panuon.UI.Silver;assembly=Panuon.UI.Silver"
    Width="1000"
    Height="500"
    pu:WindowXCaption.HideBasicButtons="True"
    BorderThickness="0" 
    WindowStartupLocation="CenterScreen"
    WindowState="Maximized"
    xmlns:vm="clr-namespace:HQ.fResApp.ViewModel"  
    mc:Ignorable="d">
    <Window.DataContext>
        <vm:MainVModel/>
    </Window.DataContext>
    <Grid>
        <Grid x:Name="HasDataBlock">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="140" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            
            <!--  左侧菜单栏  -->
            <Grid
                Grid.Column="0"
                Margin="0,-35,0,0"
                Background="#394050">
                <Grid.RowDefinitions>
                    <RowDefinition Height="80" />
                    <RowDefinition />
                    <RowDefinition Height="80" />
                </Grid.RowDefinitions>
                <!--  系统Logo  -->
                <TextBlock
                    Grid.Row="0"
                    Padding="50,30,50,30"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    Background="#282e3a"
                    FontFamily="Segoe UI"
                    FontSize="23"
                    FontWeight="Bold"
                    Foreground="White">
                    <Run>蜀 味</Run>
                    <Run Foreground="#FF67DA82">正 道</Run>
                    <TextBlock.Effect>
                        <DropShadowEffect
                            BlurRadius="10"
                            Opacity="0.5"
                            ShadowDepth="0"
                            Color="White" />
                    </TextBlock.Effect>
                </TextBlock>

                <!--  菜单列表    -->
                <TreeView
                    x:Name="trMenu"
                    Grid.Row="1"
                    pu:TreeViewHelper.ItemHeight="100"
                    pu:TreeViewHelper.SelectedBackground="#AA3366"
                    pu:TreeViewHelper.SelectedForeground="#ffffff"
                    pu:TreeViewHelper.TreeViewStyle="Classic"
                    Background="Transparent"
                    BorderBrush="White"
                    Foreground="#efefef"
                    ItemsSource="{Binding MenuItems}"
                    SelectedItemChanged="TvMenu_SelectionChanged">
                    <TreeView.ItemContainerStyle>
                        <Style BasedOn="{StaticResource {x:Type TreeViewItem}}" TargetType="{x:Type TreeViewItem}">
                            <Setter Property="IsSelected" Value="{Binding IsSelect}" />
                        </Style>
                    </TreeView.ItemContainerStyle>
                    <TreeView.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding Path=TreeViewItemModel}">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition />
                                    <RowDefinition />
                                </Grid.RowDefinitions>
                                <Image
                                    Margin="-15,-5,0,0"
                                    Source="{Binding Path=Icon}"
                                    Stretch="None" />
                                <TextBlock
                                    Grid.Row="1"
                                    Margin="-15,10,0,0"
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center"
                                    FontSize="16"
                                    FontWeight="Bold"
                                    Text="{Binding Path=Header}" />
                            </Grid>
                        </HierarchicalDataTemplate>
                    </TreeView.ItemTemplate>
                </TreeView>

                <!--  退出系统  -->
                <StackPanel
                    Grid.Row="2"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    Cursor="Hand"
                    Orientation="Horizontal"
                    ToolTip="退出系统前,请确保当前操作已经无误!">
                    <Button
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        pu:ButtonHelper.ButtonStyle="Link"
                        pu:ButtonHelper.HoverBrush="White"
                        pu:ButtonHelper.Icon="/HQ.fResApp;component/Resources/icon/out.png"
                        pu:IconHelper.Width="45"
                        Click="WindowX_Closing"
                        Content="退出"
                        FontFamily="Segoe UI"
                        FontSize="17"
                        FontWeight="ExtraBold"
                        Foreground="White" />
                </StackPanel>
            </Grid>
            
            <!--  右侧内容栏  -->
            <Grid Grid.Column="1" Margin="0,-35,0,0">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="80" />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
                            <TextBlock
                                x:Name="txtStoreName1"
                                Margin="20,0,0,0"
                                FontFamily="Champagne &amp; Limousines"
                                FontSize="23"
                                FontWeight="Bold"
                                Foreground="#5f5f5f"
                                Text="牛牪犇火锅店"
                                Visibility="Collapsed" />
                        </StackPanel>
                        <StackPanel
                            Grid.Column="1"
                            Margin="0,0,20,0"
                            HorizontalAlignment="Right"
                            VerticalAlignment="Center"
                            Orientation="Horizontal">
                            <pu:DropDown
                                HorizontalAlignment="Left"
                                VerticalAlignment="Top"
                                Cursor="Hand">
                                <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
                                    <TextBlock
                                        x:Name="txtStoreName"
                                        Margin="0,10,5,0"
                                        VerticalAlignment="Center"
                                        FontSize="16"
                                        FontWeight="DemiBold"
                                        Foreground="#909399"
                                        Text="牛牪犇火锅(安南旗舰店)" />
                                    <Border
                                        x:Name="uheadimg"
                                        Width="45"
                                        Height="45"
                                        Margin="0,5,20,0"
                                        BorderBrush="#F0F0F0"
                                        BorderThickness="1"
                                        CornerRadius="30">
                                        <Border.Background>
                                            <ImageBrush ImageSource="/HQ.fResApp;component/Resources/icon/logo.png" />
                                        </Border.Background>
                                    </Border>
                                </StackPanel>
                                <pu:DropDown.Child>
                                    <Grid Width="100">
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="55" />
                                            <RowDefinition Height="55" />
                                        </Grid.RowDefinitions>
                                        <Grid Margin="15,0" Cursor="Hand">
                                            <Button
                                                Height="30"
                                                VerticalAlignment="Center"
                                                pu:ButtonHelper.HoverBrush="Transparent"
                                                Background="Transparent"
                                                Click="ToUInfo_Click"
                                                Content="个人中心"
                                                FontFamily="/Panuon.UI.Silver;component/Resources/#fontawesome"
                                                Foreground="#909399" />
                                        </Grid>
                                        <Border
                                            Width="80"
                                            VerticalAlignment="Bottom"
                                            BorderBrush="#EEEEEE"
                                            BorderThickness="0,0,0,1" />
                                        <Grid
                                            Grid.Row="1"
                                            Margin="15,0"
                                            Cursor="Hand">
                                            <Button
                                                Height="30"
                                                VerticalAlignment="Center"
                                                pu:ButtonHelper.HoverBrush="Transparent"
                                                Background="Transparent"
                                                Click="WindowX_Closing"
                                                Content="退出登录"
                                                FontFamily="/Panuon.UI.Silver;component/Resources/#fontawesome"
                                                Foreground="#909399" />
                                        </Grid>
                                    </Grid>
                                </pu:DropDown.Child>
                            </pu:DropDown>
                        </StackPanel>
                    </Grid>
                    <ContentControl x:Name="ContentControl" Grid.Row="1" />
                </Grid>
            </Grid>
        </Grid>        
    </Grid>
</pu:WindowX>

3、主窗体业务逻辑

这块业务是指当登录成功后,必须将用户拥有的菜单显示出来,所以涉及到后台的用户,角色,菜单多个表的关联,因此必须从dal到bll的代码。

4、主窗体视图模型

后台逻辑代码

using HQ.COMM;
using HQ.fResApp.BaseModel;
using HQ.fResApp.ViewModel;
using Panuon.UI.Silver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace HQ.fResApp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : WindowX
    {
        private static IDictionary<string, Type> _partialViewDic; 

        static MainWindow()
        {
            _partialViewDic = new Dictionary<string, Type>();
            var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.FullName.StartsWith("HQ.fResApp"));
            assembly.GetTypes().Where(x => x.Namespace.StartsWith("HQ.fResApp.UControls") && x.IsSubclassOf(typeof(UserControl))).ToList().ForEach(x => _partialViewDic.Add(x.Name, x));
        }

        public MainWindow()
        {
            InitializeComponent();
        }

        #region EventHandler
         
        private void TvMenu_SelectionChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            try
            {
                //系统首次加载
                if (!IsLoaded)
                {
                    var _tag = _partialViewDic["CanTaiGuanLi"];
                    ContentControl.Content = Activator.CreateInstance(_tag);
                }
                //选择不同菜单项
                var selectedItem = trMenu.SelectedItem as TreeViewItemModel;
                var curTag = selectedItem.Tag;
                if (curTag.IsNullOrEmpty()) return;
                if (_partialViewDic.ContainsKey(curTag))
                {
                    var _tag = _partialViewDic[curTag];
                    ContentControl.Content = Activator.CreateInstance(_tag);
                }
                else
                {
                    ContentControl.Content = null;
                }
            }
            catch (Exception ex)
            {
                ContentControl.Content = null;
                Logger.Default.Error("切换系统菜单异常", ex);
            }
        }
        private void WindowX_Closing(object sender, RoutedEventArgs e)
        {
            var result = MessageBoxX.Show("退出系统前,请确认当前操作处理完结?", "提示", this, MessageBoxButton.OKCancel);
            if (result == MessageBoxResult.OK)
            {
                Application.Current.Shutdown();
            }
        }
       
        private void ToUInfo_Click(object sender, RoutedEventArgs e)
        {
            
        }
       
        #endregion

    }
}

5、测试效果

点击左侧不同菜单呈现不同内容

原创不易,打字截图不易,走过路过,不要错过,欢迎点赞,收藏,转载,复制,抄袭,留言,动动你的金手指,早日实现财务自由!


网站公告

今日签到

点亮在社区的每一天
去签到