wpf实现抽屉效果,一般就一个动画显示就完事了,我这用到了,就研究了一下,用装饰器给控件添加遮罩层,然后在上面添加抽屉控件,虽然麻烦了点,也算是自己研究的成果了。

看看效果:

下面就看看代码:

首先是新建一个装饰器类,和之前用过的文章:WPF 使用装饰器给控件添加遮罩层 中用的是同样的,

 public class SimpleAdorner : Adorner{private UIElement child;public SimpleAdorner(UIElement adornedElement) : base(adornedElement){}//Adorner 直接继承自 FrameworkElement,//没有Content和Child属性,//自己添加一个,方便向其中添加我们的控件public UIElement Child{get => child;set{if (value == null){RemoveVisualChild(child);}else{AddVisualChild(value);}child = value;}}//重写VisualChildrenCount 表示此控件只有一个子控件protected override int VisualChildrenCount => 1;//控件计算大小的时候,我们在装饰层上添加的控件也计算一下大小protected override Size ArrangeOverride(Size finalSize){child?.Arrange(new Rect(finalSize));return finalSize;}//重写GetVisualChild,返回我们添加的控件protected override Visual GetVisualChild(int index){if (index == 0 && child != null) return child;return base.GetVisualChild(index);}}

然后新建一个类:

 [TemplatePart(Name = DrawerGrid,Type =typeof(Grid))][TemplatePart(Name = CloseButton,Type =typeof(Button))]public class GDrawer : ContentControl{public Action Closed;private const string DrawerGrid = "DrawerGrid";private const string CloseButton = "CloseButton";private Grid _drawerGrid;private Button _closeButton;public override void OnApplyTemplate(){base.OnApplyTemplate();_drawerGrid = GetTemplateChild(DrawerGrid) as Grid;_closeButton = GetTemplateChild(CloseButton) as Button;_closeButton.Click += (s, e) => IsOpen = false;Loaded += OnLoaded;}private void OnLoaded(object sender, RoutedEventArgs e){IsOpen = true;}public bool IsOpen{get { return (bool)GetValue(IsOpenProperty); }set { SetValue(IsOpenProperty, value); }}public static readonly DependencyProperty IsOpenProperty =DependencyProperty.Register("IsOpen", typeof(bool), typeof(GDrawer), new PropertyMetadata(false,(s,e)=> {var drawer = s as GDrawer;if(e.NewValue is bool b && b){drawer.StartAnimationIn();}else{drawer.StartAnimationOut();}}));private async void StartAnimationIn(float seconds=0.3f){var sb = new Storyboard();var offset = _drawerGrid.ActualWidth;var animation = new ThicknessAnimation{Duration = new Duration(TimeSpan.FromSeconds(seconds)),From = new Thickness(-offset,0 , offset,0 ),To = new Thickness(0)};Storyboard.SetTargetProperty(animation, new PropertyPath("Margin"));sb.Children.Add(animation);sb.Begin(_drawerGrid);await Task.Delay((int)(seconds * 1000));}private async void StartAnimationOut(float seconds=0.3f){var sb = new Storyboard();var offset = _drawerGrid.ActualWidth;var animation = new ThicknessAnimation{Duration = new Duration(TimeSpan.FromSeconds(seconds)),From = new Thickness(0),To = new Thickness(-offset, 0, offset, 0),};Storyboard.SetTargetProperty(animation, new PropertyPath("Margin"));sb.Children.Add(animation);sb.Begin(_drawerGrid);await Task.Delay((int)(seconds * 1000));Closed?.Invoke();}}

这个就是抽屉效果的实现类了,

然后,在App.xaml里添加样式和资源 :

<Style TargetType="local:GDrawer"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="local:GDrawer"><Grid x:Name="DrawerGrid" MinWidth="300" MinHeight="100" HorizontalAlignment="Left" VerticalAlignment="Stretch"Background="White"><Button x:Name="CloseButton" Margin="10" Width="50" Height="30" HorizontalAlignment="Right" VerticalAlignment="Top">关闭</Button><ContentPresenter /></Grid></ControlTemplate></Setter.Value></Setter>
</Style><local:GDrawer x:Key="LeftDrawer"><TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="18" Foreground="Red">这是内容</TextBlock></local:GDrawer>

最后,来到MainWindow窗口,xaml代码如下:

<Window x:Class="WPFDemos.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WPFDemos"mc:Ignorable="d"x:Name="widnow"WindowStartupLocation="CenterScreen"Title="title" Height="500" Width="1000"><Grid x:Name="grid" Background="LightBlue"><!--定义装饰层--><AdornerDecorator/><Button Click="Button_Click" HorizontalAlignment="Center" VerticalAlignment="Center">打开</Button></Grid>
</Window>

MainWindow窗体后台代码:

 public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void Button_Click(object sender, RoutedEventArgs e){ShowModal(grid);}SimpleAdorner _adorner = null;public void ShowModal(Visual visual){//获取visual上面的第一个AdornerLayerAdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(visual);//创建我们定义的Adornervar drawer = FindResource("LeftDrawer") as GDrawer;drawer.Closed = () => adornerLayer.Remove(_adorner);_adorner = _adorner?? new SimpleAdorner(adornerLayer){Child = new Border(){Background = new SolidColorBrush(Color.FromArgb(150, 0, 0, 0)),Child = drawer}};adornerLayer.Add(_adorner);}}

这样就完成了,

如果喜欢,点个赞呗~

WPF 用装饰器制作抽屉效果相关推荐

  1. WPF自定义控件 —— 装饰器

    摘自:http://www.cnblogs.com/Curry/archive/2009/09/16/1567757.html 顾名思义就是装饰用的,也就是说不改变原有的控件结构,但可以为控件添加一些 ...

  2. wpf-利用装饰器制作 彩色字体+可选中+可复制 的textblock

    效果如下图所示: 实现要点: 彩色字体可以用TextBlock的Run实现 "可选中"可以通过装饰器实现 注意鼠标事件处理 前台 <ScrollViewer Width=&q ...

  3. 计时装饰器python_使用python装饰器制作计时函数

    本代码作用,使用装饰器做一个计时函数,使用此计时函数来装饰其他的函数,计算其他函数的执行耗时 代码如下: import time def jishi(fun1): #定义装饰函数jishi,参数是fu ...

  4. 关于WPF装饰器的笔记

    关于装饰器 参见这几篇文章,较为详尽 详解Adorner Layer http://www.cnblogs.com/nankezhishi/archive/2010/07/10/adornerlaye ...

  5. Python的装饰器

    详解Python的装饰器 本文源码 https://github.com/tobyqin/python_decorator Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都 ...

  6. Python(三)对装饰器的理解

    装饰器是 Python 的一个重要部分,也是比较难理解和使用好的部分.下面对装饰器做一下简单整理 1. 前言 装饰器实际上是应用了设计模式里,装饰器模式的思想: 在不概念原有结构的情况下,添加新的功能 ...

  7. python装饰器类-基于类的python装饰器

    python装饰器函数其实是这样一个接口约束,它必须接受一个callable对象作为参数,然后返回一个callable对象.在Python中一般callable对象都是函数,但也有例外.只要某个对象重 ...

  8. 一文读懂 @Decorator 装饰器——理解 VS Code 源码的基础

    作者:easonruan,腾讯 CSIG 前端开发工程师 1. 装饰器的样子 我们先来看看 Decorator 装饰器长什么样子,大家可能没在项目中用过 Decorator 装饰器,但多多少少会看过下 ...

  9. C语言版:装饰器模式

    C语言装饰器模式实现 C语言是面向过程的一门语言,更注重过程,是一个一个函数进行一个一个去执行 是这么一个过程,那么我们怎样来实现用C语言来实现类似装饰器模式的效果呢? 每个函数是一个单独的过程,这个 ...

最新文章

  1. 走在技术前沿,今年最火的top5 +Java开源项目
  2. 三甲医院需要部署哪些网络安全设备
  3. vnc连接linux时出现黑屏
  4. linux变量赋值用中括号,Shell脚本定义变量和重新赋值
  5. UVA 12563 Jin Ge Jin Qu hao
  6. python计算2的平方代码_计算平方根
  7. Java 设计模式 之 单例模式(Singleton)
  8. c语言如何输出10个空格,新人提问:如何将输出时每行最后一个空格删除
  9. VALSE2022内容总结
  10. 再见了飞信,再见了青春
  11. Java 调用阿里云小蜜示例代码
  12. 路由器回执路由配置_路由器接路由器设置详细图文教程
  13. HMI-44-【多媒体】开启新篇章
  14. JS屏蔽功能类(屏蔽F5,退格键,空格键......
  15. Office 365导出PDF带备注页
  16. 干货分享:win10如何彻底清理C盘垃圾
  17. Gorm学习(四)基础:关联
  18. 在线对弈web服务公司笔试题
  19. Error: Parse Error: Expected HTTP/
  20. Python取代VBA?先问C#答应否

热门文章

  1. js split参数为无效字符_js使用split函数按照多个字符对字符串进行分割的方法
  2. 无法访问你试图使用的功能所在的网络位置_[steam实用工具]解决无法访问商店/社区/好友列表的问题...
  3. PHP检测远端文件是否存在
  4. 博客在线——Wireshark基本用法
  5. 第六次作业—例行报告
  6. python访问数据库
  7. web上传大文件的配置
  8. tcp/ip ---数据封装过程
  9. System.FormatException: GUID 应包含带 4 个短划线的 32 位数(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。...
  10. 【iCore3 双核心板】例程二十二:LAN_UDP实验——以太网数据传输