当前位置:网站首页>C # WPF realizes undo redo function
C # WPF realizes undo redo function
2022-06-27 11:58:00 【CodeOfCC】
List of articles
Preface
do wpf Sometimes you need to undo the redo function in the interface , Although some wpf Control has its own Undo function , However, in some complex scenarios, you still need to implement the undo redo function , For example, custom whiteboards or video clips, etc , This article will introduce how to simply implement an undo redo object , And provide use examples .
One 、 Concrete realization
Because the implementation is relatively simple , Here, the principle is explained in detail . Use one List Set plus a subscript index That is, all functions can be realized .
1、 Complete code
Undoable.cs
using System;
using System.Collections.Generic;
namespace AC
{
/// <summary>
/// Undo redo object
/// ceate by xin 2022.6.26
/// </summary>
public class Undoable
{
/// <summary>
/// revoke
/// </summary>
public void Undo()
{
if (index >-1)
{
_steps[index--].Undo();
}
}
/// <summary>
/// redo
/// </summary>
public void Redo()
{
if (index < _steps.Count-1)
{
_steps[++index].Redo();
}
}
/// <summary>
/// eliminate
/// </summary>
public void Clear()
{
_steps.Clear();
index = -1;
}
/// <summary>
/// Add operation
/// </summary>
/// <param name="undo"> revoke </param>
/// <param name="redo"> 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 });
}
// Operation steps
class Step
{
public Action Redo {
set; get; }
public Action Undo {
set; get; }
}
// Record the steps
List<Step> _steps = new List<Step>();
// Subscript of the current operation
int index = -1;
}
}
Two 、 Examples of use
1、 Drag controls
(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=" revoke " Click="Button_Click"></Button>
<Button Width="70" Height="20" Content=" redo " 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();
// Is the mouse pressed
bool _isMouseDown = false;
// Mouse down position
Point _mouseDownPosition;
// Press the button of the control with the mouse Margin
Thickness _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(() => {
// revoke
c.Margin = oldMargin;
}, () => {
// redo
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) Results the preview

summary
That's what we're going to talk about today , This article briefly introduces the implementation of undo redo , Generally speaking, it is relatively easy , Especially with Action To record the operation , This will be more flexible , You can use it directly lambda As a parameter .
边栏推荐
- 【TcaplusDB知识库】TcaplusDB运维单据介绍
- Youboxun attended the openharmony technology day to create a new generation of secure payment terminals
- QStyle类用法总结(二)
- 旭日3SDB,安装原版ros
- 【TcaplusDB知识库】TcaplusDB数据导入介绍
- 【TcaplusDB知识库】TcaplusDB-tcapsvrmgr工具介绍(一)
- Popular science of device review: popular science of innovative medical device series - sternum plate products
- 动态规划【三】(区间dp)石子合并
- c/s 架构
- I.MX6ULL启动方式
猜你喜欢

QStyle类用法总结(二)

The wonderful use of 0 length array in C language
![[tcapulusdb knowledge base] tcapulusdb doc acceptance - create business introduction](/img/a4/c3255ce17516348f703f7f21511555.png)
[tcapulusdb knowledge base] tcapulusdb doc acceptance - create business introduction

On ticheck
![[tcapulusdb knowledge base] Introduction to tcapulusdb tcapsvrmgr tool (I)](/img/04/b1194ca3340b23a4fb2091d1b2a44d.png)
[tcapulusdb knowledge base] Introduction to tcapulusdb tcapsvrmgr tool (I)

MapReduce principle analysis (in-depth source code)

This privatized deployed enterprise knowledge base makes telecommuting a zero distance

巅峰小店APP仿站开发玩法模式讲解源码分享

Open source model library of flying propeller industry: accelerating the development and application of enterprise AI tasks

Summary of qstype class usage (II)
随机推荐
0基础了解电商系统如何对接支付渠道
MapReduce实战小案例(自定义排序、二次排序、分组、分区)
内存四区(栈,堆,全局,代码区)
[tcapulusdb knowledge base] Introduction to tcapulusdb data import
dried food! What problems will the intelligent management of retail industry encounter? It is enough to understand this article
Mqtt protocol stack principle and interaction flow chart
pull request
【TcaplusDB知识库】TcaplusDB-tcapsvrmgr工具介绍(一)
[tcapulusdb knowledge base] Introduction to tcapulusdb system management
【TcaplusDB知识库】TcaplusDB单据受理-创建游戏区介绍
Jerry's seamless looping [chapter]
C/s architecture
【面试高频题】难度 1.5/5,LCS 模板题
杰理之一直喂狗会频繁开关中断导致定时器【篇】
Wechat applet payment password input
从零开始搭建物联网系统
R语言fpc包的dbscan函数对数据进行密度聚类分析、plot函数可视化聚类图
【TcaplusDB知识库】TcaplusDB数据导入介绍
Don't miss it. New media operates 15 treasure official account to share
【TcaplusDB知识库】TcaplusDB单据受理-建表审批介绍