当前位置:网站首页>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 .
边栏推荐
- 千万不要错过,新媒体运营15个宝藏公众号分享
- Redis 分布式锁15问,看看你都掌握了哪些?
- Safe landing practice of software supply chain under salesforce containerized ISV scenario
- C语言0长度数组的妙用
- 巅峰小店APP仿站开发玩法模式讲解源码分享
- Jerry added an input capture channel [chapter]
- Thinkphp6 interface limits user access frequency
- I.MX6ULL启动方式
- L'utilisation de C language 0 length Array
- JSP custom tag
猜你喜欢
![[tcapulusdb knowledge base] tcapulusdb doc acceptance - table creation approval introduction](/img/da/449a1e215885597a67344e2a6edf0f.png)
[tcapulusdb knowledge base] tcapulusdb doc acceptance - table creation approval introduction

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

【TcaplusDB知识库】Tmonitor系统升级介绍

优博讯出席OpenHarmony技术日,全新打造下一代安全支付终端
![Jerry's serial port communication serial port receiving IO needs to set digital function [chapter]](/img/d1/5beed6c86c4fdc024c6c9c66fbffb8.png)
Jerry's serial port communication serial port receiving IO needs to set digital function [chapter]

【TcaplusDB知识库】TcaplusDB-tcapsvrmgr工具介绍(一)

1. Mx6ull startup mode

matlab习题 —— 创建 50 行 50 列全零矩阵、全 1 矩阵、单位矩阵、对角矩阵,输出矩阵第135号元素。

进程间通信详解

Jwas: a Bayesian based GWAS and GS software developed by Julia
随机推荐
15+ urban road element segmentation application, this segmentation model is enough!
The R language uses the follow up The plot function visualizes the longitudinal follow-up map of multiple ID (case) monitoring indicators, and uses stress The labels parameter adds label information t
Excel中输入整数却总是显示小数,如何调整?
星际争霸的虫王IA退役2年搞AI,自叹不如了
[tcapulusdb knowledge base] tcapulusdb doc acceptance - create business introduction
R语言glm函数构建二分类logistic回归模型(family参数为binomial)、使用AIC函数比较两个模型的AIC值的差异(简单模型和复杂模型)
QStyle类用法总结(三)
[tcapulusdb knowledge base] Introduction to tcapulusdb data structure
数学知识——博弈论(巴什博奕、尼姆博奕、威佐夫博奕)思路及例题
Jerry's seamless looping [chapter]
Xuri 3sdb, installing the original ROS
建木持续集成平台v2.5.0发布
杰理之DAC输出方式设置【篇】
[tcapulusdb knowledge base] tcapulusdb business data backup introduction
Histrix工作原理
The R language uses the DOTPLOT function of epidisplay package to visualize the frequency of data points in different intervals in the form of point graph, specifies the grouping parameters with the b
In depth analysis of error solutions and problems in dynamic loading of unity shadow and outline components
C# wpf 实现撤销重做功能
【TcaplusDB知识库】TcaplusDB单据受理-创建业务介绍
杰理之一直喂狗会频繁开关中断导致定时器【篇】