最近看到一个比较漂亮的UI主界面,该UI是用左边的页签进行导航,比较有特色,就想着尝试用WPF来实现一下。经过一番尝试,基本上将UI设计图的效果用WPF程序进行了实现。下面介绍一下主要的思路:

1 UI设计

 该UI的PSD设计图效果如下:

  UI结构分析:先可以把UI分成上下两个区域,上面是一个区域放置一些appName,用户信息和配置按钮等,下面的再分成竖向的页签导航区域和内容区。但从WPF程序实现上来说,可以有多种区域划分方法,每个人的划分方法不同。

2 UI切图

  内容区域的图片不做切图,它会动态根据左边的导航菜单的配置动态进行加载内容。本文只实现主界面UI框架。在Photoshop中可以在图片所在图层进行重命名,例如A的图层有一个按钮图标,可以将其命名为A.png(注意之前需要勾选Photoshop的生成【图片资源】项目),那么就可以在PSD文件同级目录中生成一个同名的文件夹,里面就有A.png的图标了!

3 WPF UI布局实现

  PSD设计的UI需要转换成WPF程序,必须要将其UI结构用WPF的布局进行重新梳理,我的布局划分(主要是Grid)代码如下所示:

 <Window
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
x:Class="WpfTabNavigation.MainWindow"
Title="MainWindow" Height="610" Width="880"
AllowsTransparency="True" WindowStyle="None"
Background="{x:Null}" MouseLeftButtonDown="Window_MouseLeftButtonDown" >
<Grid Background="Black" d:IsHidden="True">
<Grid x:Name="gridForm" d:IsHidden="True">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" x:Name="gridFormLeft"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- toolbar-->
<StackPanel Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Margin="1,1,1,0" Orientation="Horizontal" d:IsHidden="True" >
<StackPanel.Background>
<ImageBrush ImageSource="images/toolbarbg.png" Stretch="UniformToFill"/>
</StackPanel.Background> <Grid Width="878" d:IsHidden="True">
<Grid.RowDefinitions>
<RowDefinition Height="36" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="0.8*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="appName" FontWeight="Bold" FontSize="22" Margin="8,2,2,2" Text="WPF DashBoard" Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" d:IsHidden="True" />
<TextBlock x:Name="authorName" FontWeight="Bold" FontSize="10" Margin="8,0,2,8" Text="JackWang-Cumt@cnblogs.com" Foreground="#FF463E3E" Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" d:IsHidden="True" /> <TextBlock x:Name="userInfo" FontWeight="Bold" FontSize="16" Margin="60,18,18,18" Text="Welcome to Admin" Foreground="#FF333333" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Center" d:IsHidden="True" /> <DatePicker x:Name="datePick" Margin="22.4,18,194.4,18" Foreground="#FF333333" Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Center" Width="160" d:IsHidden="True"/>
<Image Source="images/email.png" Stretch="Uniform" Margin="0,15,112,19" Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" Width="26" HorizontalAlignment="Right" d:IsHidden="True"/>
<Image Source="images/notify.png" Stretch="Uniform" Margin="254.4,9,102.4,10.2" Grid.Column="2" Grid.Row="0" Height="20" Width="20" d:IsHidden="True"/>
<TextBlock x:Name="notifyCount" FontSize="9" Margin="259.4,12,99.4,15.2" Grid.Column="2" Grid.Row="0" Text="18" Foreground="#FFFFFFFF" VerticalAlignment="Center" Width="18" d:IsHidden="True"/> <Image Source="images/settings.png" Stretch="Uniform" Margin="0,15,72,19" Grid.Column="2" Grid.Row="0" Height="26" Width="30" HorizontalAlignment="Right" Grid.RowSpan="2" d:IsHidden="True" />
<Image x:Name="Logout" MouseLeftButtonDown="Logout_MouseLeftButtonDown_1" Source="images/logout.png" Stretch="Uniform" Margin="0,15,36,19" Grid.Column="2" Grid.Row="0" Height="26" Width="30" HorizontalAlignment="Right" Grid.RowSpan="2" Cursor="Hand" d:IsHidden="True"/> </Grid>
</StackPanel>
<!--end toolbar-->
<StackPanel x:Name="LeftBar" Background="#FF333333" Margin="0,0.2,0,0" Grid.Column="0" Grid.Row="1" d:IsHidden="True" >
<TabControl x:Name="LeftTabControl" TabStripPlacement="Left" Background="#FF00D1E5" Height="548" d:IsHidden="True">
<TabItem Header="Home" Height="80" Margin="0,0,-3,0" Width="80" FontWeight="Bold" Style="{DynamicResource TabItemStyle}" TextOptions.TextFormattingMode="Display" MouseMove="TabItem_MouseMove_1" d:IsHidden="True">
<TabItem.Background>
<ImageBrush ImageSource="images/homeicon.png" />
</TabItem.Background> <StackPanel Margin="2,6,2,2" d:IsHidden="True" >
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" MouseLeftButtonDown="Label_MouseLeftButtonDown_1" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Web Design" Foreground="White" Margin="0,6,0,6" MouseLeftButtonDown="Label_MouseLeftButtonDown_2" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Icon Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="PSD Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Line Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Paper Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
</StackPanel> </TabItem>
<!-- Margin="0,0,-3,0" 中的-3为了消除右边的边框-->
<TabItem Header="Projects" Height="80" Margin="0,0,-3,0" Width="80" FontWeight="Bold" Style="{DynamicResource TabItemStyle}" TextOptions.TextFormattingMode="Display" d:IsHidden="True">
<TabItem.Background>
<ImageBrush ImageSource="images/projects.png" />
</TabItem.Background>
<!--内容区-->
<StackPanel Margin="2,6,2,2" d:IsHidden="True" >
<Label Content="CSS Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="JS Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="HTML Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
</StackPanel> <!--end 内容区--> </TabItem> <TabItem Header="Tasks" Height="80" Margin="0,0,-3,0" Width="80" FontWeight="Bold" Style="{DynamicResource TabItemStyle}" TextOptions.TextFormattingMode="Display" d:IsHidden="True">
<TabItem.Background>
<ImageBrush ImageSource="images/taskicon.png" />
</TabItem.Background>
<!--内容区-->
<StackPanel Margin="2,6,2,2" d:IsHidden="True" >
<Label Content="AI Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
</StackPanel> <!--end 内容区-->
</TabItem> <TabItem Header="Calendar" Height="80" Margin="0,0,-3,0" Width="80" FontWeight="Bold" Style="{DynamicResource TabItemStyle}" TextOptions.TextFormattingMode="Display" d:IsHidden="True">
<TabItem.Background>
<ImageBrush ImageSource="images/calendaricon.png" />
</TabItem.Background>
<!--内容区-->
<StackPanel Margin="2,6,2,2" d:IsHidden="True" >
<Label Content="DOC Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
</StackPanel> <!--end 内容区-->
</TabItem> <TabItem Header="Statistics" Height="80" Margin="0,0,-3,0" Width="80" FontWeight="Bold" Style="{DynamicResource TabItemStyle}" TextOptions.TextFormattingMode="Display" d:IsHidden="True">
<TabItem.Background>
<ImageBrush ImageSource="images/graphicon.png" />
</TabItem.Background>
<!--内容区-->
<StackPanel Margin="2,6,2,2" d:IsHidden="True" >
<Label Content="JD Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
<Label Content="Graphic Design" Foreground="White" Margin="0,6,0,6" d:IsHidden="True"/>
<Border d:IsHidden="True" >
<Image Source="images/line.png" d:IsHidden="True"/>
</Border>
</StackPanel> <!--end 内容区-->
</TabItem> </TabControl>
</StackPanel>
<!--end tab-->
<StackPanel Grid.Column="1" Grid.Row="1" Background="White" Margin="0,0,1,0" Orientation="Horizontal" d:IsHidden="True">
<!-- Expand button-->
<Border x:Name="spliter" Width="32" Height="64" Margin="-10" Cursor="Hand" MouseLeftButtonDown="spliter_MouseLeftButtonDown" d:IsHidden="True">
<Border.Background>
<ImageBrush ImageSource="images/panelexpand.png" Stretch="UniformToFill"/>
</Border.Background>
</Border> <!--end Expand button-->
<!--加载其他的page xaml-->
<Frame x:Name="pageContainer" Margin="33,18,33,18" ScrollViewer.CanContentScroll="True" NavigationUIVisibility="Hidden" d:IsHidden="True" />
<!--加载其他的xaml窗体,但是必须frm.show才能显示,有闪烁
<ContentControl Name="frmContainter" Margin="2" ></ContentControl>
-->
</StackPanel>
<!--end Content--> </Grid>
</Grid>
</Window>

  主界面中用 AllowsTransparency="True" WindowStyle="None" Background="{x:Null}" 对窗体的边框进行隐藏。坐标的页签是tabControl控件,但是必须要重新定义其Style样式:Style="{DynamicResource TabItemStyle},其中TabItemStyle的代码如下:

 <ResourceDictionary
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
<SolidColorBrush x:Key="TabControlNormalBorderBrush" Color="#8C8E94"/>
<!-- 应该在此定义资源字典条目。-->
<Style x:Key="TabControlStyle" TargetType="{x:Type TabControl}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Padding" Value="4,4,4,4"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="{StaticResource TabControlNormalBorderBrush}"/>
<Setter Property="Background" Value="#F9F9F9"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto" MinHeight="84.5"/>
<RowDefinition x:Name="RowDefinition1"/>
</Grid.RowDefinitions>
<Border x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local" Margin="0">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Opacity="1"/>
</Border>
<Canvas x:Name="HeaderPanel" HorizontalAlignment="Stretch" Height="Auto" Width="Auto" IsItemsHost="True"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#FF00D1E5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TabItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="3,3,3,1" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="TabItemHotBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#EAF6FD" Offset="0.15"/>
<GradientStop Color="#D9F0FC" Offset=".5"/>
<GradientStop Color="#BEE6FD" Offset=".5"/>
<GradientStop Color="#A7D9F5" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="TabItemSelectedBackground" Color="#F9F9F9"/>
<SolidColorBrush x:Key="TabItemHotBorderBrush" Color="#3C7FB1"/>
<SolidColorBrush x:Key="TabItemDisabledBackground" Color="#F4F4F4"/>
<SolidColorBrush x:Key="TabItemDisabledBorderBrush" Color="#FFC9C7BA"/>
<Style x:Key="TabItemStyle" TargetType="{x:Type TabItem}">
<Setter Property="FocusVisualStyle" Value="{StaticResource TabItemFocusVisual}"/>
<Setter Property="Foreground" Value="#FF00D1E5"/>
<Setter Property="Padding" Value="6,1,6,1"/>
<Setter Property="BorderBrush" Value="{StaticResource TabControlNormalBorderBrush}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid SnapsToDevicePixels="true">
<Grid.RowDefinitions>
<RowDefinition Height="0.66*"/>
<RowDefinition Height="0.34*"/>
</Grid.RowDefinitions>
<Border x:Name="Bd" BorderThickness="0" CornerRadius="3" BorderBrush="Black" Margin="0" Grid.RowSpan="2" Visibility="Hidden">
<Border.Background>
<ImageBrush ImageSource="/WpfTabNavigation;component/images/hoverbutton.png" />
</Border.Background>
</Border>
<Border x:Name="fg" BorderThickness="0" CornerRadius="3" BorderBrush="#FF00D1D1" Margin="0" Grid.RowSpan="2" Visibility="Hidden" RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<Border.Background>
<ImageBrush ImageSource="/WpfTabNavigation;component/images/hoverbutton.png"/>
</Border.Background>
</Border>
<!--文本颜色设置-->
<TextBlock Name="PART_Text" Margin="0,0.333,0,3.833" TextWrapping="Wrap" VerticalAlignment="Stretch" d:LayoutOverrides="Height" Grid.Row="1" HorizontalAlignment="Center" Text="{TemplateBinding Header}" Foreground="Black" > <TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property= "Foreground" Value="#FF00D1E5"/>
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value="True">
<Setter Property= "Foreground" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style> </TextBlock>
<!--图标-->
<Border x:Name="ico" BorderThickness="0" CornerRadius="3" BorderBrush="Black" Margin="4,4,4.25,0" Grid.RowSpan="1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="32" Height="32" Background="{TemplateBinding Background}" RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true"/>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Visibility" TargetName="Bd" Value="Visible"/>
<Setter Property="Panel.ZIndex" TargetName="ico" Value="1"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="false"/>
<Condition Property="IsMouseOver" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" TargetName="fg" Value="Visible"/>
<Setter Property="RenderTransform" TargetName="ico">
<Setter.Value>
<TransformGroup>
<ScaleTransform ScaleX="1.05" ScaleY="1.05"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Setter.Value>
</Setter>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

4 WPF逻辑实现

 UI界面有了,还必须附加一些业务逻辑:

 1)窗体拖动;

         private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}

2)单击页签菜单项目,进行导航到相应的页面;

         private void Label_MouseLeftButtonDown_2(object sender, MouseButtonEventArgs e)
{
this.pageContainer.Source = new Uri("pages/Page_Chart2.xaml", UriKind.RelativeOrAbsolute);
}

  在主界面中有一个名为pageContainer的Frame控件,它能加载Page类型的界面(注意不是window).详细页面的正太分布图形用的Oxyplot控件。

 3)坐标的页签菜单栏可以隐藏和显示

         private bool __isLeftHide = false;
private void spliter_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//显示和隐藏
__isLeftHide =! __isLeftHide;
if (__isLeftHide)
{
this.gridForm.ColumnDefinitions[].Width = new GridLength(1d);
}
else
{
this.gridForm.ColumnDefinitions[].Width = new GridLength(200d);
} }

  由于Grid没有visiable属性,我这里获取页签所在的Grid列,然后设置其width属性为1,将其隐藏。

5 最终效果

  最终的效果截图如下(感谢园友斧正:下图的正太分布是正态分布哈!):

6 未实现的功能

  左边菜单的颜色,想着不选中显示RGB(0,209,229),选中显示RGB(51,51,51)或者黑色。但尝试了一些方法还未实现。若有园友知道思路的话,欢迎指教!

7 代码开源

  此代码进行开源,代码托管到GitHub上,https://github.com/JackWangCUMT/WPFTabNavigation

-----------------------------------------------------------------------------------------------------------------

8 完善

  上面提到字体无法变更的问题,经过查阅资料已经解决,这里主要用到触发器设置中的TargetName属性,将设置的值应用到名为TargetName设置的控件对应属性上:

     <Style x:Key="TabItemStyle" TargetType="{x:Type TabItem}">
......
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid SnapsToDevicePixels="true">
......
<!--页签文本 PART_Text-->
<TextBlock Name="PART_Text" Margin="0,0.333,0,3.833" TextWrapping="Wrap" VerticalAlignment="Stretch" d:LayoutOverrides="Height" Grid.Row="1" HorizontalAlignment="Center" Text="{TemplateBinding Header}" Foreground="#FF00D1E5" > </TextBlock>
<!--图标-->
......
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true"/>
<!--页签选中后进行触发-->
<Trigger Property="IsSelected" Value="true">
<Setter Property="Visibility" TargetName="Bd" Value="Visible"/>
<Setter Property="Panel.ZIndex" TargetName="ico" Value="1"/>
<!--在控件模板下,一个控件的Triggers可利用TargetName属性对其他控件的样式-->
<Setter Property="Foreground" TargetName="PART_Text" Value="Black" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="false"/>
<Condition Property="IsMouseOver" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" TargetName="fg" Value="Visible"/>
<Setter Property="RenderTransform" TargetName="ico">
<Setter.Value>
<TransformGroup>
<ScaleTransform ScaleX="1.05" ScaleY="1.05"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Setter.Value>
</Setter>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

另外将日期控件进行了样式完善,这里对TextBox控件利用自定义样式将其设置为具有可以下拉选择日期的功能。

WPF如何实现一个漂亮的页签导航UI的更多相关文章

  1. ajax实现分页页签

    在一些搜索列表的页面中,我们会遇到一些需要处理页签的需求,一般这样的页面,要么是在JSP中处理,每次都跳页.这样做是个很方便的方法.但是如果页面上有很多和列表无关,每次都需要重新渲染是不是显得慢了一些 ...

  2. jeesite框架前端 tabPage页签刷新功能。

    js主动刷新当前页签的js代码 原本想找一下jeesite有没有主动刷新当前页面的内置方法. 官方文档找了一大堆,找都找不到,也可能我这个需求比较少人需要. tab标签页有一个右键刷新页签功能 查看编 ...

  3. 使用原生js与jQuery分别实现一个简单的tab页签

    tab页签通常适用于空间有限而内容较多同时兼顾页面美观度不给用户一种信息过量视觉疲劳的情形.使用面非常广,下面我们用两种方法简单实现之. 首先,构建页面元素.页签的可点击部分我们通常用列表来承载,包括 ...

  4. [K/3Cloud] 首页增加一个自定义页签及页面内容

    在K3Cloud登录后的门户首页增加一个页签,如增加一个[BBS论坛] 2013-7-30 11:18:51 上传 下载附件 (84.81 KB)  增加页签 可以这么来做: 进入BOS IDE ,找 ...

  5. JavaScript选项卡/页签/Tab的实现

    选项卡,也称页签,英文用Tab(Module-Tabs)表示.Tab将不同的内容重叠放在一个布局块内,重叠的内容区里每次只有其中一个是可见的. Tab可以在相同的空间里展示更多的信息,它把相似的主题分 ...

  6. C# 重绘tabControl,添加关闭按钮(页签)

    C# 重绘tabControl,添加关闭按钮(页签) 调用方法 参数: /// <summary> /// 初始化 /// </summary> /// <param n ...

  7. 实现TabView(页签)效果

    今天花了点时间,设计了一个网页上用的tabview(页签.tabcontrol)效果.个人觉得实现得比较不错,网页元素用得比较少,js代码也比较精练.测试了一下支持IE.FireFox以及chrome ...

  8. PS网页设计教程XXIV——从头设计一个漂亮的网站

    作为编码者,美工基础是偏弱的.我们可以参考一些成熟的网页PS教程,提高自身的设计能力.套用一句话,“熟读唐诗三百首,不会作诗也会吟”. 本系列的教程来源于网上的PS教程,都是国外的,全英文的.本人尝试 ...

  9. 浅谈WPF页间导航

    浅谈WPF页间导航 使用导航的目的是从一个页面进入到另一个页面.无论是预先决定的线性顺序(向导)还是基于层次的用户驱动程序(大部分网站的形式),或者动态生成的路径,主要有3种方法实现:调用Naviga ...

随机推荐

  1. iOS调试

    iOS高效调试 写代码难免出现bug.储备些调试技能绝对能够提高你的工作效率,让bug无所遁形.下面就和大家分享一些我在工作中常用的iOS调试小技能. 1. 打印 最简单,基础的调试方法就是打印日志了 ...

  2. OpenCV进阶之路:一个简化的视频摘要程序

    一.前言 视频摘要又称视频浓缩,是对视频内容的一个简单概括,先通过运动目标分析,提取运动目标,然后对各个目标的运动轨迹进行分析,将不同的目标拼接到一个共同的背景场景中,并将它们以某种方式进行组合.视频 ...

  3. C语言操作符优先级

    C语言操作符优先级 优先级 运算符 含    义 要求运算 对象的个数 结合方向 1 () [] -> . 圆括号 下标运算符 指向结构体成员运算符 结构体成员运算符 自左至右 2 ! 逻辑非运 ...

  4. 【转】Servlet与web.xml的配置

    Web.xml常用元素<web-app><display-name></display-name>定义了WEB应用的名字<description>< ...

  5. 通过EasyUI Tree说明SQL GUID和自增列ID的使用场景

    最新在开发中用到了EasyUI里面的Tree,通过API可以看到这个Tree的数据格式如下: 其中ID比较重要,API也说了,最开始我考虑到GUID比自增ID多占用了一些空间,所以采用的自增ID,测试 ...

  6. RPi 2B GPIO 测试

    /************************************************************************************** * RPi 2B GPI ...

  7. Eclipse4.3正式版已发布

    Eclipse4.3正式版已发布,传送门http://www.eclipse.org/downloads/

  8. 创建的docker容器时间显示错误/date错误/时区错误

    前几天在测试应用的功能时,发现存入数据库中的数据create_time或者update_time字段总是错误,其他数据都是正常的,只有关于时间的字段是错误的. 进入linux服务器中查看,也没有任何的 ...

  9. 用python批量修改文件名

    从youtube上当下来百来首mv,每个都需要去掉视频,这还挺好弄得,格式工厂一弄就完了,但是文件名,都带有乱七八糟的*啥的巴拉巴拉的,咋修改啊,几百首总不可能一个一个rename吧 #批量修改文件名 ...

  10. Retrofit原理

    Retrofit原理解析最简洁的思路 Retrofit 工作原理总结 从架构角度看Retrofit的作用.原理和启示 Retrofit主要是在create方法中采用动态代理模式实现接口方法:这个过程构 ...