C# WPF 左侧菜单右侧内容布局效果实现
我们要做的效果是这样的,左侧是可折叠的菜单栏,右侧是内容区域,点击左侧的菜单项右侧内容区域则相应地切换。
wpf实现的话,我的办法是用一个tabcontrol,修改tabcontrol的样式模板,首先将控件的TabStripPlacement设置为left使tabcontrol的item header部分靠左内容靠右,然后用一个Expander将TabPanel包住实现可折叠菜单效果,最后就是把用到的控件样式修改一下即可。
先看下效果图:

WPF做出来的效果图:

未完善的问题:
不能添加多个可折叠菜单,我暂时没想到比较好的办法。
新建一个项目,名字随你,新建一个自定义用户控件前台修改为:
<TabControl x:Class="cloundmusic_left.controls.itabcontrol"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:cloundmusic_left.controls"
mc:Ignorable="d"
d:DesignHeight="" d:DesignWidth="">
<TabControl.Resources>
<!--折叠菜单的箭头按钮-->
<ControlTemplate x:Key="ExpanderToggleButton"
TargetType="{x:Type ToggleButton}">
<Border Background="{TemplateBinding Background}" Width="{TemplateBinding Width}" x:Name="Border"
> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="CollapsedArrow">
<DiscreteObjectKeyFrame KeyTime=""
Value="{x:Static Visibility.Hidden}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="ExpandededArrow">
<DiscreteObjectKeyFrame KeyTime=""
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Margin="0,0,13,0" HorizontalAlignment="Right" VerticalAlignment="Center">
<Path x:Name="CollapsedArrow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z">
<Path.Fill>
<SolidColorBrush Color="#7d7d7d" />
</Path.Fill>
</Path>
<Path x:Name="ExpandededArrow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="Collapsed"
Data="M 0 4 L 4 0 L 8 4 Z">
<Path.Fill>
<SolidColorBrush Color="#7d7d7d" />
</Path.Fill>
</Path>
</Grid>
</Border>
</ControlTemplate> <Style TargetType="{x:Type Expander}">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Foreground" Value="#7d7d7d"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Border BorderBrush="#e1e1e2" BorderThickness="0,0,1,0">
<Grid Background="#f5f5f7">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition x:Name="ContentRow"
Height="" />
</Grid.RowDefinitions> <Border MinHeight="" x:Name="Border"
Grid.Row=""
> <Grid VerticalAlignment="Center"> <ContentPresenter
Margin="" ContentSource="Header"
RecognizesAccessKey="True" /> <ToggleButton Background="Transparent" Width="{Binding ElementName=Border,Path=ActualWidth}" Panel.ZIndex="" OverridesDefaultStyle="True"
Template="{StaticResource ExpanderToggleButton}"
IsChecked="{Binding IsExpanded, Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}"> </ToggleButton>
</Grid>
</Border>
<Border x:Name="Content"
Grid.Row=""
> <ContentPresenter/>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded"
Value="True">
<Setter TargetName="ContentRow"
Property="Height"
Value="{Binding DesiredHeight, ElementName=Content}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style> <Style TargetType="{x:Type TabItem}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid SnapsToDevicePixels="true">
<Border Cursor="Hand" MinWidth="" MinHeight="" x:Name="Bd" CornerRadius="" Background="Transparent" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="3,0,0,0" Padding="" Margin="">
<Grid VerticalAlignment="Center" HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal"> <ContentPresenter x:Name="Content" Margin="17,0,0,0" ContentSource="Header" HorizontalAlignment="Left" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/> </StackPanel> </Grid>
</Border>
</Grid> <ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="false"> <Setter Property="Foreground" Value="#5c5c5c"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true"> <Setter Property="Foreground" Value="#000000"/>
</Trigger> <Trigger Property="IsSelected" Value="true">
<Setter Property="Panel.ZIndex" Value=""/>
<Setter Property="Background" TargetName="Bd" Value="#e6e7ea"/> <Setter Property="Foreground" Value="#000000"/>
<Setter Property="BorderThickness" TargetName="Bd" Value="3,0,0,0"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="#c62f2f"/> </Trigger> </ControlTemplate.Triggers>
</ControlTemplate> </Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabControl.Style>
<Style TargetType="{x:Type TabControl}">
<Setter Property="OverridesDefaultStyle"
Value="True" />
<Setter Property="TabStripPlacement"
Value="Left" />
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:itabcontrol}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> <!--可折叠菜单-->
<Expander Header="{TemplateBinding iTitle}" Grid.Column="">
<!--菜单项-->
<TabPanel x:Name="HeaderPanel" IsItemsHost="True"
KeyboardNavigation.TabIndex=""
Background="Transparent" />
</Expander>
<!--右侧内容区域-->
<Border x:Name="Border"
Grid.Column="" KeyboardNavigation.TabNavigation="Local"
KeyboardNavigation.DirectionalNavigation="Contained"
KeyboardNavigation.TabIndex=""> <ContentPresenter x:Name="PART_SelectedContentHost"
Margin=""
ContentSource="SelectedContent" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style> </TabControl.Style>
</TabControl>
修改后你的vs也许会抱一个错:


这个报错就像vs错误列表里的警告一样,没啥卵用,不用理它,程序是可以运行的
。
ok继续,后台代码加一个依赖属性:
public string iTitle
{
get { return (string)GetValue(iTitleProperty); }
set { SetValue(iTitleProperty, value); }
} public static readonly DependencyProperty iTitleProperty =
DependencyProperty.Register("iTitle", typeof(string), typeof(itabcontrol));
然后只要在界面中使用这个控件即可。
呃我发现这个项目并没有什么难点,实现方法开头也说了,所以这里不一步步讲了。
值得一提的是,加入的Expander也就是可折叠菜单的header代表菜单名,这里我是把修改的这个TabControl写在一个自定义控件里的,在界面调用的时候默认是无法给它设置内容的,所以我们要在这个自定义控件中加入一个依赖属性,然后在样式中绑定这个属性。这里就涉及到一个比较有意思的东西,在样式中绑定一个属性也许你没接触过,但是你一定知道Binding的用法,而在样式中是没办法这么用的,那该怎么去做呢?相信你看完代码就知道了。
项目下载:
C# WPF 左侧菜单右侧内容布局效果实现的更多相关文章
- 左侧菜单栏右侧内容(改进,有js效果)
(如有错敬请指点,以下是我工作中遇到并且解决的问题)上一篇文章是简洁版 这是上一篇文章的改进. 上一篇文章的左侧菜单是没有子目录的. 这是效果图: 左侧菜单代码: <div class=&quo ...
- HTMLCSS实现左侧固定宽度右侧内容可滚动
在做移动端页面的时候,经常会碰到一个div中分左右两个div,左侧div固定宽度或百分比,右侧div中内容左右溢出,需要左右滑动才可以浏览到全部内容,为此写了一个demo. 处理这个问题的核心关键点是 ...
- HTML和CSS实现左侧固定宽度右侧内容可滚动
在做移动端页面的时候,经常会碰到一个div中分左右两个div,左侧div固定宽度或百分比,右侧div中内容左右溢出,需要左右滑动才可以浏览到全部内容,为此写了一个demo. 处理这个问题的核心关键点是 ...
- C# 窗体 类似framest 左侧点击右侧显示 左侧菜单右侧显示
首先托一个splitContainer调节大小位置 然后进行再新创建一个窗体名为add 在左侧拖入button按钮 进入代码阶段 更改属性 public Main() { InitializeComp ...
- css布局之左侧固定右侧自适应布局
参考代码如下: <form id="form1" style="height:100%; overflow:hidden;"> <div st ...
- bootstrap实现左侧图片右侧文字布局
效果图 代码 通过class="media-left"来控制相对位置 <!DOCTYPE html> <html> <head lang=" ...
- ifram 实现左侧菜单,右侧显示内容
一般都是左侧的导航栏中的a标签中写一个target(a标签有target属性), 右侧的div标签中写一个iframe,在iframe中有name的属性,在左侧a标签中的target写上iframe中 ...
- ionic js 侧栏菜单 把主要内容区域从一边拖动到另一边,来让左侧或右侧的侧栏菜单进行切换
ionic 侧栏菜单 一个容器元素包含侧边菜单和主要内容.通过把主要内容区域从一边拖动到另一边,来让左侧或右侧的侧栏菜单进行切换. 效果图如下所示: 用法 要使用侧栏菜单,添加一个父元素<ion ...
- ajax实现简单的点击左侧菜单,右侧加载不同网页
实现:ajax实现点击左侧菜单,右侧加载不同网页(在整个页面无刷新的情况下实现右侧局部刷新,用到ajax注意需要在服务器环境下运行,从HBuilder自带的服务器中打开浏览效果即可) 原理:ajax的 ...
随机推荐
- linux的几个内核镜像格式Image 和 u-boot启动内核和文件系统时的一些环境变量的设置
关于编译powerpc linux的几个Image参考原文 http://blog.sina.com.cn/s/blog_86a30b0c0100wfzt.html 转载▼ PowerPC架构 L ...
- Internet连接共享只能上qq不能打开网页的问题解决
作者:朱金灿 来源:http://blog.csdn.net/clever101 之前我写过一篇<Windows共享上网的做法>,在设置共享网络时是有一个家庭网络连接的选项的,如下图: 但 ...
- 【81.82%】【codeforces 740B】Alyona and flowers
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- Java中关键字throw和throws的区别
==========================================题外话===================================================== 今 ...
- javascrit开发的基本代码结构的
今天看到群里一个demo,简单看了一下. 然后自己就写了一个通用的javascrit开发的基本代码结构的js文件. 代码例如以下: (function($,win){ //定义全局变量对象 var o ...
- angular的学习参考材料
原文地址:https://www.jianshu.com/p/b9db7bb3d4ec 目的 其实写这篇文章的主要目的是为了提供给那些刚刚入门angular或者有意学习angular的读者准备的. 我 ...
- 安装使用jupyter(原来的notebook)
1.安装pyzmq 使用pip install pyzmq,安装不成功. 使用easy_install.exe pyzmq.成功安装. 2.安装tornado pip tornado 安装完尚不成功. ...
- iOS开发之Quartz2D 五:UIKIT 绘图演练,画文字,画图片
#import "DrawView.h" @implementation DrawView -(void)awakeFromNib { // //画图片 // UIImage *i ...
- JAVA SkipList 跳表 的原理和使用例子
跳跃表是一种随机化数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(log n)平均时间),并且对并发算法友好. 关于跳跃表的具体介绍可以参考MIT的公开课:跳跃表 跳跃表的应 ...
- 解析C#内存管理
C#内存管理解析 前言:对于很多的C#程序员来说,经常会很少去关注其内存的释放,他们认为C#带有强大的垃圾回收机制,所有不愿意去考虑这方面的事情,其实不尽然,很多时候我们都需要考虑C#内存的管理问题, ...