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的 ...
随机推荐
- Learn from Architects of Buildings
 Learn from Architects of Buildings Keith Braithwaite Architecture is a social act and the material ...
- 修复STS4 server中没有Tomcat的问题(必看,官方推荐,包教包会,国内首发)
版权声明:原创.欢迎转载,转载请注明来源,谢谢. https://blog.csdn.net/qq_41910280/article/details/83279129 修复STS4 server中没有 ...
- Android中图形截取的方式介绍
在Android的应用中,有时候我们想仅仅显示一部分图像,这时候就要求图形截图. 1.随意截取图像的方法,以下我们具体介绍一下android中的重要类--Bitmap public final cla ...
- 记录一下phper的学习方向
我是一个懒惰的人,吃了多年技术老本儿,对新技术缺乏学习动力,仗着逻辑思维的优势处理问题 http://www.topthink.com/topic/26730.html
- 使用ionic3快速开发webapp(一)
Ionic可以让我们使用web技术快速构建接近原生体验的跨平台移动应用. 一.安装ionic 1.需要先安装 Node.js(版本8.x之上): 2.安装cordova 和 ionic: $ npm ...
- kernel build & preempt-rt patch & xenomai
提前准备好 linux 内核源代码,假设是 x86 系统.能够去下载原生内核(Vanilla kernel): wget https://www.kernel.org/pub/linux/kernel ...
- 【Solr专题之九】SolrJ教程 分类: H4_SOLR/LUCENCE 2014-07-28 14:31 2351人阅读 评论(0) 收藏
一.SolrJ基础 1.相关资料 API:http://lucene.apache.org/solr/4_9_0/solr-solrj/ apache_solr_ref_guide_4.9.pdf:C ...
- Android 输入框弹出样式
在androidMainfest.xml文件里 在Activity中设置 [A]stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置 [B]stateU ...
- Android 开发--CMakeList调用本地so文件
这里写代码片Android开发常常遇到Java调用so文件的情况,本文介绍一下Google最近新推出的应用在android studio中的方法–cmakelist.txt格式调用. so文件分为jn ...
- JS和CSS压缩部署,提高访问效率
一直想把项目中的js和css压缩下,今天终于搞定了. 先说说几个注意的问题,目标影响着你对应的解决办法:1.压缩后的文件,是否要直接覆盖旧的文件2. 单个压缩文件重命名,还是整个目录换个名字,同时文件 ...