文章目录

  • 前言
  • 一、具体实现
    • 1、完整代码
  • 二、使用示例
    • 1、拖动控件
      • (1)MainWindow.xaml
      • (2)MainWindow.xaml.cs
      • (3)效果预览
  • 总结

前言

做wpf界面的时候有时需要撤销重做功能,虽然一些wpf控件自带撤销功能,但是在一些复杂的场景还是需要自己实现撤销重做功能,比如自定义的白板或者视频剪辑器等等,本文将介绍如何简单的实现一个撤销重做对象,并提供使用示例。


一、具体实现

由于实现相对简单,这里就具体对原理进行说明了。用一个List集合加一个下标index即可以实现所有功能。

1、完整代码

Undoable.cs

using System;
using System.Collections.Generic;
namespace AC
{/// <summary>/// 撤销重做对象/// ceate by xin 2022.6.26/// </summary>public class Undoable{     /// <summary>/// 撤销/// </summary>public void Undo(){if (index >-1){_steps[index--].Undo();}       }/// <summary>/// 重做/// </summary>public void Redo(){if (index < _steps.Count-1){_steps[++index].Redo();}}/// <summary>/// 清除/// </summary>public void Clear(){_steps.Clear();index = -1;}/// <summary>/// 添加操作/// </summary>/// <param name="undo">撤销</param>/// <param name="redo">重做</param>public void Add(Action undo, Action redo){index++;if (index < _steps.Count) _steps.RemoveRange(index, _steps.Count-index);_steps.Add(new Step() {Undo= undo, Redo = redo });}//操作步骤class Step{ public Action Redo { set; get; }public Action Undo { set; get; }}//记录的步骤List<Step> _steps = new List<Step>();//当前操作的下标int index = -1;}
}

二、使用示例

1、拖动控件

(1)MainWindow.xaml

<Window x:Class="WpfApp3.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:WpfApp3"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><StackPanel Orientation="Horizontal" VerticalAlignment="Top" ><Button Width="70" Height="20" Content="撤销"  Click="Button_Click"></Button><Button  Width="70" Height="20" Content="重做" Click="Button_Click_1"></Button></StackPanel><Rectangle   Width="240" Height=" 120"  RadiusX="20" RadiusY="20" Fill="RoyalBlue"  PreviewMouseDown="Rectangle_PreviewMouseDown" PreviewMouseMove="Rectangle_PreviewMouseMove" PreviewMouseUp="Rectangle_PreviewMouseUp"></Rectangle><Ellipse  HorizontalAlignment="Left" Width="120" Height=" 120"   Fill="GreenYellow"  PreviewMouseDown="Rectangle_PreviewMouseDown" PreviewMouseMove="Rectangle_PreviewMouseMove" PreviewMouseUp="Rectangle_PreviewMouseUp"></Ellipse></Grid>
</Window>

(2)MainWindow.xaml.cs

using AC;
using System.Windows;
using System.Windows.Input;
namespace WpfApp3
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{Undoable _undoable=new Undoable();//鼠标是否按下bool _isMouseDown = false;//鼠标按下的位置Point _mouseDownPosition;//鼠标按下控件的MarginThickness _mouseDownMargin;public MainWindow(){InitializeComponent();}private void Rectangle_PreviewMouseDown(object sender, MouseButtonEventArgs e){var c = sender as FrameworkElement;_isMouseDown = true;_mouseDownPosition = e.GetPosition(this);_mouseDownMargin = c.Margin;c.CaptureMouse();}private void Rectangle_PreviewMouseMove(object sender, MouseEventArgs e){if (_isMouseDown){var c = sender as FrameworkElement;var pos = e.GetPosition(this);var dp = pos - _mouseDownPosition;c.Margin = new Thickness(_mouseDownMargin.Left + dp.X, _mouseDownMargin.Top + dp.Y, _mouseDownMargin.Right - dp.X, _mouseDownMargin.Bottom - dp.Y);}}private void Rectangle_PreviewMouseUp(object sender, MouseButtonEventArgs e){var c = sender as FrameworkElement;_isMouseDown = false;c.ReleaseMouseCapture();var oldMargin = _mouseDownMargin;var newMargin = c.Margin;_undoable.Add(() => {//撤销     c.Margin = oldMargin;}, () => {//重做c.Margin = newMargin;});}private void Button_Click(object sender, RoutedEventArgs e){_undoable.Undo();}private void Button_Click_1(object sender, RoutedEventArgs e){_undoable.Redo();}}
}

(3)效果预览


总结

以上就是今天要讲的内容,本文简单介绍了撤销重做的实现,总的来说还是比较容易的,尤其是是使用Action来记录操作,这样就会比较灵活,可以直接使用lambda作为参数。

C# wpf 实现自定义撤销重做功能相关推荐

  1. C++ 实现自定义撤销重做功能

    文章目录 前言 一.完整代码 二.使用示例 1.基本用法 2.gdi画线撤销 总结 前言 在使用c++做界面开发的时候,需要涉及到到撤销重做操作,尤其是实现白板功能时需要自己实现一套撤销重做功能,如果 ...

  2. Mac OS开发—Xcode给Mac应用添加编辑快捷键(剪切 复制 粘贴 全选 删除 撤销 重做)功能

    前言 笔者做Windows开发的,无奈公司有Mac OS的项目需要维护,之前没有编辑菜单的功能,需要笔者加上这个功能,笔者只能硬着头皮上.还好会c++,Mac应用里面一般都会用object-c 也可以 ...

  3. 实现编辑功能有哪几个action_Web 应用的撤销重做实现

    背景 前不久,我参与开发了团队中的一个 web 应用,其中的一个页面操作如下图所示: GIF 这个制作间页面有着类似 PPT 的交互:从左侧的工具栏中选择元素放入中间的画布.在画布中可以删除.操作(拖 ...

  4. android 自定义画笔,在Android Canvas中使用撤销/重做操作的自定义画笔

    我想使用自定义画笔&撤消/重做操作实现画布绘制应用程序.首先,我的代码完美工作,无需使用自定义画笔(包括撤消/重做操作).根据这个答案How to make custom brush for ...

  5. Qt Undo Framework学习,实现撤销、重做功能

    0. 引言 在交互应用程序中撤销和重做(Undo/Redo)能力是很重要的.像常见的软件Office,AutoCAD等,有了撤销功能,用户体验更舒服.一般都会使用Command模式来实现这一功能. 1 ...

  6. Flax撤销,重做功能梳理

    项目需要添加撤销,重做功能,调研了下flax,下面是调研的结构 引擎源码库 撤销/重做 IUndoAction UndoActionBase Serialize TransformObjectsAct ...

  7. java中系统撤销对象顺序实例,撤消/重做功能Java的对象序列化

    游戏编程与"企业应用程序"编程和"webapp编程"没有多大关系. 所以这取决于你正在做什么样的游戏,但你的方法和gaven所以这些票价与游戏状态在" ...

  8. WPF 实现自定义的笔迹橡皮擦

    本文来告诉大家使用比较底层的方法来实现 WPF 的笔迹橡皮擦 在 WPF 里面,对于笔迹来说,应该放在 Stroke 类里面,而不是作为点的集合存储.在 Stroke 类里面将作为管理笔迹的类提供笔迹 ...

  9. html自定义指针,如何自定义鼠标指针 怎样在wpf中自定义鼠标指针

    如何在ppt中自定义鼠标指针的形状? 魔兽世界怎么自定义鼠标指针 在系统 控制面板 里面鼠标属性 指针里面改就可以了 下面有个浏览 可以自定义换图案 怎样在网页中设定一整套自定义的鼠标指针? 麻烦了 ...

最新文章

  1. 提示内存不足,其它服务不能运行
  2. python官网 中文版 新闻-他说,懂中文就能学会Python,但需要这个工具
  3. 【编译原理】语言的定义
  4. JAVA设计模式 - 建造者模式
  5. Linux内核分析 - 网络[十二]:UDP模块 - socket
  6. 湖南师大计算机学信网,湖南师范大学有计算机专业硕士吗?
  7. 人工智能运行环境linux,Intel OpenVINO 人工智能推论环境搭建 (Linux) 第一章
  8. C#高级编程9 第19章 程序集
  9. (Note)欧空局多光谱卫星Sentinel-2
  10. 软考网络工程师重难点总结分享~(3)
  11. 计算机硬盘存贮量单位,硬盘存储计量单位KB、MB、GB大小换算
  12. 腾讯敏捷开发及快速迭代
  13. 华为防火墙IPSEC简单搭建
  14. 计时器操作--打点计时器
  15. python面向对象学习
  16. 『Java安全』反序列化-浅析Hessian反序列化POP链
  17. 微信小程序(4)——CSS3渐变
  18. 显卡驱动版本 与 cuda版本
  19. 华为mate40pro和华为mate30pro的区别
  20. 前端table打印被截断,如何给每一页都增加表头

热门文章

  1. 库存管理系统软件测试,软件测试库存管理系统1软件测试库存管理系统1.doc
  2. 超越平台,数据中台的业务化、服务化及开放化!
  3. 贪吃蛇java 暂停_Java实现贪吃蛇小游戏
  4. java字符串abc反转_JAVA字符串反转的三种方法
  5. 《虚拟聊天室(模仿QQ)》实验报告
  6. pdf怎样添加水印?添加图片水印的方法
  7. JS 获取文件后缀,判断文件类型(比如是否为图片格式)
  8. C语言实现从字符串s中删除所有字符c
  9. 电力预测原始数据随机森林缺失值处理
  10. OCP认证考试券及原版教材