当前位置:网站首页>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 .
边栏推荐
- Informatics Olympiad all in one 1332: [example 2-1] weekend dance
- dried food! What problems will the intelligent management of retail industry encounter? It is enough to understand this article
- R language uses GLM function to build Poisson logarithm linear regression model, processes three-dimensional contingency table data to build saturation model, uses step function to realize stepwise re
- R language uses the poisgof function of epidisplay package to test the goodness of fit of Poisson regression and whether there is overdispersion
- Jianmu continuous integration platform v2.5.0 release
- FileOutputStream
- Jerry added an input capture channel [chapter]
- 【面试高频题】难度 1.5/5,LCS 模板题
- [tcapulusdb knowledge base] tcapulusdb doc acceptance - transaction execution introduction
- Histrix工作原理
猜你喜欢

数学知识——博弈论(巴什博奕、尼姆博奕、威佐夫博奕)思路及例题
![[tcapulusdb knowledge base] tcapulusdb doc acceptance - create business introduction](/img/a4/c3255ce17516348f703f7f21511555.png)
[tcapulusdb knowledge base] tcapulusdb doc acceptance - create business introduction

What is the TCP 3-time handshake process?
![[tcaplusdb knowledge base] Introduction to tcaplusdb tcaplusadmin tool](/img/ba/f865c99f3ea9e42c85b7e906f4f076.png)
[tcaplusdb knowledge base] Introduction to tcaplusdb tcaplusadmin tool

c/s 架构

57. The core principle of flutter - layout process

Matlab exercises - create 50 rows and 50 columns of all zero matrix, all 1 matrix, identity matrix, diagonal matrix, and output the 135 element of the matrix.

Excel中输入整数却总是显示小数,如何调整?
![[tcapulusdb knowledge base] tcapulusdb doc acceptance - table creation approval introduction](/img/da/449a1e215885597a67344e2a6edf0f.png)
[tcapulusdb knowledge base] tcapulusdb doc acceptance - table creation approval introduction

QStyle类用法总结(二)
随机推荐
Wechat applet payment password input
【TcaplusDB知识库】TcaplusDB OMS业务人员权限介绍
Fork/Join 框架基本使用和原理
Jwas: a Bayesian based GWAS and GS software developed by Julia
On ticheck
How to adjust an integer that is entered in Excel but always displays decimals?
[tcapulusdb knowledge base] Introduction to tcapulusdb tcapsvrmgr tool (I)
[worthy of collection] centos7 installation MySQL complete operation command
pull request
i. Construction of mx6ull C language environment
Jerry's seamless looping [chapter]
Shell script learning notes
AutoCAD - three pruning methods
Detailed explanation of interprocess communication
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
动态规划【三】(区间dp)石子合并
[tcapulusdb knowledge base] tcapulusdb system user group introduction
Popular science of device review: popular science of innovative medical device series - sternum plate products
I.MX6ULL启动方式
【面试高频题】难度 1.5/5,LCS 模板题