Skip to content

Commit 003c4b0

Browse files
committed
Added memento pattern
1 parent 5ea1783 commit 003c4b0

15 files changed

Lines changed: 541 additions & 0 deletions
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace SoftwarePatterns.Core.Momento
2+
{
3+
public interface IMemento
4+
{
5+
object State { get; set; }
6+
}
7+
8+
public class InkCanvasMemeto : IMemento
9+
{
10+
public object State { get; set; }
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Define:
2+
Without violating encapsulation, capture and externalize an object's internal state allowing the object to be restored to this state later. Yes No N/A
3+
4+
Usage:
5+
For rollback undo
6+
Provide access to object internal state without violating encapsulation.
7+
8+
Structure:
9+
In the memento pattern the is the originator the object we wish to track the memento the object that holds its state and the caretaker that maintains the memento.
10+
11+
Example:
12+
A simple wpf drawing application with undo feature.

‎src/SoftwarePatterns.Core/SoftwarePatterns.Core.csproj‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
<Compile Include="Mediator\AircraftController.cs" />
138138
<Compile Include="Mediator\Boeing747.cs" />
139139
<Compile Include="Mediator\IAircraft.cs" />
140+
<Compile Include="Momento\IMemento.cs" />
140141
<Compile Include="Properties\AssemblyInfo.cs" />
141142
</ItemGroup>
142143
<ItemGroup>
@@ -156,6 +157,8 @@
156157
<Content Include="Iterator\ReadMe.txt" />
157158
<Content Include="LazyLoad\ReadMe.txt" />
158159
<Content Include="Mediator\ReadMe.txt" />
160+
<Content Include="Momento\ReadMe.txt" />
161+
<Content Include="PatternList.txt" />
159162
</ItemGroup>
160163
<ItemGroup />
161164
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
5+
</startup>
6+
</configuration>

‎src/SoftwarePatterns.WPF/App.xaml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<Application x:Class="SoftwarePatterns.WPF.App"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
StartupUri="MainWindow.xaml">
5+
<Application.Resources>
6+
7+
</Application.Resources>
8+
</Application>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Configuration;
4+
using System.Data;
5+
using System.Linq;
6+
using System.Threading.Tasks;
7+
using System.Windows;
8+
9+
namespace SoftwarePatterns.WPF
10+
{
11+
/// <summary>
12+
/// Interaction logic for App.xaml
13+
/// </summary>
14+
public partial class App : Application
15+
{
16+
}
17+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Window x:Class="SoftwarePatterns.WPF.MainWindow"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:wpf="clr-namespace:SoftwarePatterns.WPF"
5+
Title="MainWindow" Height="350" Width="525">
6+
<Grid>
7+
<wpf:InkCanvasWithUndo Height="auto" HorizontalAlignment="Left" Margin="10,10,0,0" x:Name="Canvas1" VerticalAlignment="Top" Width="auto"></wpf:InkCanvasWithUndo>
8+
<Label Content="Label" Name="Label1" HorizontalAlignment="Left" Margin="10,267,0,0" VerticalAlignment="Top" Width="188" Height="52"/>
9+
</Grid>
10+
</Window>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Windows;
6+
using System.Windows.Controls;
7+
using System.Windows.Ink;
8+
using System.Windows.Input;
9+
using SoftwarePatterns.Core.Momento;
10+
11+
namespace SoftwarePatterns.WPF
12+
{
13+
/// <summary>
14+
/// Interaction logic for MainWindow.xaml
15+
/// </summary>
16+
public partial class MainWindow : Window
17+
{
18+
private readonly Stack<IMemento> priorStates = new Stack<IMemento>();
19+
20+
public MainWindow()
21+
{
22+
InitializeComponent();
23+
24+
CommandBindings.Add(new CommandBinding(ApplicationCommands.Undo,
25+
OnExectedCommands));
26+
27+
Canvas1.MouseUp += Canvas1OnMouseUp;
28+
StoreState();
29+
}
30+
31+
private void Canvas1OnMouseUp(object sender, MouseButtonEventArgs mouseButtonEventArgs)
32+
{
33+
StoreState();
34+
}
35+
36+
private void OnExectedCommands(object sender, ExecutedRoutedEventArgs e)
37+
{
38+
var window = (MainWindow) sender;
39+
if (e.Command == ApplicationCommands.Undo)
40+
{
41+
window.Undo(sender, e);
42+
}
43+
}
44+
45+
private void Undo(object sender, ExecutedRoutedEventArgs executedRoutedEventArgs)
46+
{
47+
if (priorStates.Count > 1)
48+
{
49+
priorStates.Pop();
50+
var lastState = priorStates.Peek();
51+
Canvas1.SetMemento(lastState);
52+
}
53+
Label1.Content = priorStates.Count;
54+
}
55+
56+
private void StoreState()
57+
{
58+
var memento = Canvas1.CreateMemento();
59+
priorStates.Push(memento);
60+
Label1.Content = priorStates.Count;
61+
}
62+
}
63+
64+
public class InkCanvasWithUndo : InkCanvas
65+
{
66+
public IMemento CreateMemento()
67+
{
68+
var copy = Strokes.ToArray();
69+
return new InkCanvasMemeto { State = copy };
70+
}
71+
72+
public void SetMemento(IMemento memento)
73+
{
74+
Strokes = new StrokeCollection((Stroke[])memento.State);
75+
}
76+
}
77+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System.Reflection;
2+
using System.Resources;
3+
using System.Runtime.CompilerServices;
4+
using System.Runtime.InteropServices;
5+
using System.Windows;
6+
7+
// General Information about an assembly is controlled through the following
8+
// set of attributes. Change these attribute values to modify the information
9+
// associated with an assembly.
10+
[assembly: AssemblyTitle("SoftwarePatterns.WPF")]
11+
[assembly: AssemblyDescription("")]
12+
[assembly: AssemblyConfiguration("")]
13+
[assembly: AssemblyCompany("")]
14+
[assembly: AssemblyProduct("SoftwarePatterns.WPF")]
15+
[assembly: AssemblyCopyright("Copyright © 2013")]
16+
[assembly: AssemblyTrademark("")]
17+
[assembly: AssemblyCulture("")]
18+
19+
// Setting ComVisible to false makes the types in this assembly not visible
20+
// to COM components. If you need to access a type in this assembly from
21+
// COM, set the ComVisible attribute to true on that type.
22+
[assembly: ComVisible(false)]
23+
24+
//In order to begin building localizable applications, set
25+
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
26+
//inside a <PropertyGroup>. For example, if you are using US english
27+
//in your source files, set the <UICulture> to en-US. Then uncomment
28+
//the NeutralResourceLanguage attribute below. Update the "en-US" in
29+
//the line below to match the UICulture setting in the project file.
30+
31+
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32+
33+
34+
[assembly: ThemeInfo(
35+
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36+
//(used if a resource is not found in the page,
37+
// or application resource dictionaries)
38+
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39+
//(used if a resource is not found in the page,
40+
// app, or any theme specific resource dictionaries)
41+
)]
42+
43+
44+
// Version information for an assembly consists of the following four values:
45+
//
46+
// Major Version
47+
// Minor Version
48+
// Build Number
49+
// Revision
50+
//
51+
// You can specify all the values or you can default the Build and Revision Numbers
52+
// by using the '*' as shown below:
53+
// [assembly: AssemblyVersion("1.0.*")]
54+
[assembly: AssemblyVersion("1.0.0.0")]
55+
[assembly: AssemblyFileVersion("1.0.0.0")]

‎src/SoftwarePatterns.WPF/Properties/Resources.Designer.cs‎

Lines changed: 71 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)