diff --git a/Gen3Hex/Gen3Hex.csproj b/Gen3Hex/Gen3Hex.csproj
index cf2b278f..86ae9696 100644
--- a/Gen3Hex/Gen3Hex.csproj
+++ b/Gen3Hex/Gen3Hex.csproj
@@ -60,10 +60,12 @@
+
+
diff --git a/Gen3Hex/View/HexContent.cs b/Gen3Hex/View/HexContent.cs
index e94ccc60..b95eb4ab 100644
--- a/Gen3Hex/View/HexContent.cs
+++ b/Gen3Hex/View/HexContent.cs
@@ -17,8 +17,8 @@ namespace HavenSoft.Gen3Hex.View {
#region ViewPort
- public ViewPort ViewPort {
- get { return (ViewPort)GetValue(ViewPortProperty); }
+ public IViewPort ViewPort {
+ get { return (IViewPort)GetValue(ViewPortProperty); }
set { SetValue(ViewPortProperty, value); }
}
@@ -50,8 +50,8 @@ namespace HavenSoft.Gen3Hex.View {
private void OnViewPortPropertyChanged(object sender, PropertyChangedEventArgs e) {
var propertyChangesThatRequireRedraw = new[] {
- nameof(ViewPort.SelectionStart),
- nameof(ViewPort.SelectionEnd),
+ nameof(ViewModel.ViewPort.SelectionStart),
+ nameof(ViewModel.ViewPort.SelectionEnd),
};
if (propertyChangesThatRequireRedraw.Contains(e.PropertyName)) {
@@ -74,23 +74,23 @@ namespace HavenSoft.Gen3Hex.View {
InputBindings.Add(keyBinding);
}
- AddKeyCommand(nameof(ViewPort.MoveSelectionStart), Direction.Up, Key.Up);
- AddKeyCommand(nameof(ViewPort.MoveSelectionStart), Direction.Down, Key.Down);
- AddKeyCommand(nameof(ViewPort.MoveSelectionStart), Direction.Left, Key.Left);
- AddKeyCommand(nameof(ViewPort.MoveSelectionStart), Direction.Right, Key.Right);
+ AddKeyCommand(nameof(ViewModel.ViewPort.MoveSelectionStart), Direction.Up, Key.Up);
+ AddKeyCommand(nameof(ViewModel.ViewPort.MoveSelectionStart), Direction.Down, Key.Down);
+ AddKeyCommand(nameof(ViewModel.ViewPort.MoveSelectionStart), Direction.Left, Key.Left);
+ AddKeyCommand(nameof(ViewModel.ViewPort.MoveSelectionStart), Direction.Right, Key.Right);
- AddKeyCommand(nameof(ViewPort.MoveSelectionEnd), Direction.Up, Key.Up, ModifierKeys.Shift);
- AddKeyCommand(nameof(ViewPort.MoveSelectionEnd), Direction.Down, Key.Down, ModifierKeys.Shift);
- AddKeyCommand(nameof(ViewPort.MoveSelectionEnd), Direction.Left, Key.Left, ModifierKeys.Shift);
- AddKeyCommand(nameof(ViewPort.MoveSelectionEnd), Direction.Right, Key.Right, ModifierKeys.Shift);
+ AddKeyCommand(nameof(ViewModel.ViewPort.MoveSelectionEnd), Direction.Up, Key.Up, ModifierKeys.Shift);
+ AddKeyCommand(nameof(ViewModel.ViewPort.MoveSelectionEnd), Direction.Down, Key.Down, ModifierKeys.Shift);
+ AddKeyCommand(nameof(ViewModel.ViewPort.MoveSelectionEnd), Direction.Left, Key.Left, ModifierKeys.Shift);
+ AddKeyCommand(nameof(ViewModel.ViewPort.MoveSelectionEnd), Direction.Right, Key.Right, ModifierKeys.Shift);
- AddKeyCommand(nameof(ViewPort.Scroll), Direction.Up, Key.Up, ModifierKeys.Control);
- AddKeyCommand(nameof(ViewPort.Scroll), Direction.Down, Key.Down, ModifierKeys.Control);
- AddKeyCommand(nameof(ViewPort.Scroll), Direction.Left, Key.Left, ModifierKeys.Control);
- AddKeyCommand(nameof(ViewPort.Scroll), Direction.Right, Key.Right, ModifierKeys.Control);
+ AddKeyCommand(nameof(IViewPort.Scroll), Direction.Up, Key.Up, ModifierKeys.Control);
+ AddKeyCommand(nameof(IViewPort.Scroll), Direction.Down, Key.Down, ModifierKeys.Control);
+ AddKeyCommand(nameof(IViewPort.Scroll), Direction.Left, Key.Left, ModifierKeys.Control);
+ AddKeyCommand(nameof(IViewPort.Scroll), Direction.Right, Key.Right, ModifierKeys.Control);
- AddKeyCommand(nameof(ViewPort.Undo), null, Key.Z, ModifierKeys.Control);
- AddKeyCommand(nameof(ViewPort.Redo), null, Key.Y, ModifierKeys.Control);
+ AddKeyCommand(nameof(IViewPort.Undo), null, Key.Z, ModifierKeys.Control);
+ AddKeyCommand(nameof(IViewPort.Redo), null, Key.Y, ModifierKeys.Control);
}
protected override void OnMouseDown(MouseButtonEventArgs e) {
@@ -99,15 +99,17 @@ namespace HavenSoft.Gen3Hex.View {
if (e.ChangedButton != MouseButton.Left) return;
Focus();
- ViewPort.SelectionStart = ControlCoordinatesToModelCoordinates(e);
- CaptureMouse();
+ if (ViewPort is ViewPort editableViewPort) {
+ editableViewPort.SelectionStart = ControlCoordinatesToModelCoordinates(e);
+ CaptureMouse();
+ }
}
protected override void OnMouseMove(MouseEventArgs e) {
base.OnMouseMove(e);
if (!IsMouseCaptured) return;
- ViewPort.SelectionEnd = ControlCoordinatesToModelCoordinates(e);
+ ((ViewPort)ViewPort).SelectionEnd = ControlCoordinatesToModelCoordinates(e);
}
protected override void OnMouseUp(MouseButtonEventArgs e) {
@@ -118,7 +120,9 @@ namespace HavenSoft.Gen3Hex.View {
protected override void OnMouseWheel(MouseWheelEventArgs e) {
base.OnMouseWheel(e);
- ViewPort.ScrollValue -= Math.Sign(e.Delta);
+ if (ViewPort is ViewPort editableViewPort) {
+ editableViewPort.ScrollValue -= Math.Sign(e.Delta);
+ }
}
protected override void OnRender(DrawingContext drawingContext) {
@@ -147,8 +151,10 @@ namespace HavenSoft.Gen3Hex.View {
}
protected override void OnTextInput(TextCompositionEventArgs e) {
- ViewPort.Edit(e.Text);
- e.Handled = true;
+ if (ViewPort is ViewPort editableViewPort) {
+ editableViewPort.Edit(e.Text);
+ e.Handled = true;
+ }
}
private void UpdateViewPortSize() {
diff --git a/Gen3Hex/ViewModel/CompositeViewPort.cs b/Gen3Hex/ViewModel/CompositeViewPort.cs
new file mode 100644
index 00000000..0406e26a
--- /dev/null
+++ b/Gen3Hex/ViewModel/CompositeViewPort.cs
@@ -0,0 +1,63 @@
+using HavenSoft.Gen3Hex.Model;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Windows.Input;
+
+namespace HavenSoft.Gen3Hex.ViewModel {
+ public class CompositeViewPort : ViewModelCore, IViewPort {
+ public HexElement this[int x, int y] => throw new NotImplementedException();
+
+ public int Width { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public int Height { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public int MinimumScroll => throw new NotImplementedException();
+
+ public int ScrollValue => throw new NotImplementedException();
+
+ public int MaximumScroll => throw new NotImplementedException();
+
+ public ObservableCollection Headers => throw new NotImplementedException();
+
+ public ICommand Scroll => throw new NotImplementedException();
+
+ public string Name => throw new NotImplementedException();
+
+ public ICommand Save => throw new NotImplementedException();
+
+ public ICommand SaveAs => throw new NotImplementedException();
+
+ public ICommand Undo => throw new NotImplementedException();
+
+ public ICommand Redo => throw new NotImplementedException();
+
+ public ICommand Copy => throw new NotImplementedException();
+
+ public ICommand Clear => throw new NotImplementedException();
+
+ public ICommand Goto => throw new NotImplementedException();
+
+ public ICommand Back => throw new NotImplementedException();
+
+ public ICommand Forward => throw new NotImplementedException();
+
+ public ICommand Close => throw new NotImplementedException();
+
+ public event EventHandler OnError;
+ public event EventHandler Closed;
+ public event NotifyCollectionChangedEventHandler CollectionChanged;
+
+ public IViewPort CreateChildView(int offset) {
+ throw new NotImplementedException();
+ }
+
+ public IReadOnlyList Find(string search) {
+ throw new NotImplementedException();
+ }
+
+ public bool IsSelected(Point point) {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Gen3Hex/ViewModel/EditorViewModel.cs b/Gen3Hex/ViewModel/EditorViewModel.cs
index 3dec8f56..9f683624 100644
--- a/Gen3Hex/ViewModel/EditorViewModel.cs
+++ b/Gen3Hex/ViewModel/EditorViewModel.cs
@@ -11,9 +11,14 @@ namespace HavenSoft.Gen3Hex.ViewModel {
private readonly IFileSystem fileSystem;
private readonly List tabs;
- private readonly StubCommand newCommand, open, save, saveAs, saveAll, close, closeAll, undo, redo, cut, copy, paste, delete, back, forward, gotoCommand, showGoto, clearError;
+ private readonly StubCommand newCommand, open, save, saveAs, saveAll, close, closeAll;
+ private readonly StubCommand undo, redo, cut, copy, paste, delete;
+ private readonly StubCommand back, forward, gotoCommand, showGoto, find, findPrevious, findNext, showFind, clearError;
private readonly Dictionary, EventHandler> forwardExecuteChangeNotifications;
+ private (IViewPort tab, int)[] recentFindResults;
+ private int currentFindResultIndex;
+
public ICommand New => newCommand;
public ICommand Open => open;
public ICommand Save => save;
@@ -31,6 +36,10 @@ namespace HavenSoft.Gen3Hex.ViewModel {
public ICommand Forward => forward;
public ICommand Goto => gotoCommand;
public ICommand ShowGoto => showGoto;
+ public ICommand Find => find;
+ public ICommand FindPrevious => findPrevious;
+ public ICommand FindNext => findNext;
+ public ICommand ShowFind => showFind;
public ICommand ClearError => clearError;
private bool gotoControlVisible;
@@ -38,7 +47,22 @@ namespace HavenSoft.Gen3Hex.ViewModel {
get => gotoControlVisible;
private set {
TryUpdate(ref gotoControlVisible, value);
- if (value) ClearError.Execute();
+ if (value) {
+ ClearError.Execute();
+ FindControlVisible = false;
+ }
+ }
+ }
+
+ private bool findControlVisible;
+ public bool FindControlVisible {
+ get => findControlVisible;
+ private set {
+ TryUpdate(ref findControlVisible, value);
+ if (value) {
+ ClearError.Execute();
+ GotoControlVisible = false;
+ }
}
}
@@ -110,6 +134,34 @@ namespace HavenSoft.Gen3Hex.ViewModel {
CanExecute = CanAlwaysExecute,
Execute = arg => GotoControlVisible = (bool)arg,
};
+ find = new StubCommand {
+ CanExecute = CanAlwaysExecute,
+ Execute = arg => FindExecuted((string)arg),
+ };
+ findPrevious = new StubCommand {
+ CanExecute = arg => recentFindResults?.Length != 0,
+ Execute = arg => {
+ currentFindResultIndex--;
+ if (currentFindResultIndex < 0) currentFindResultIndex += recentFindResults.Length;
+ var (tab, offset) = recentFindResults[currentFindResultIndex];
+ SelectedIndex = tabs.IndexOf(tab);
+ tab.Goto.Execute(offset.ToString("X2"));
+ },
+ };
+ findNext = new StubCommand {
+ CanExecute = arg => recentFindResults?.Length != 0,
+ Execute = arg => {
+ currentFindResultIndex++;
+ if (currentFindResultIndex >= recentFindResults.Length) currentFindResultIndex -= recentFindResults.Length;
+ var (tab, offset) = recentFindResults[currentFindResultIndex];
+ SelectedIndex = tabs.IndexOf(tab);
+ tab.Goto.Execute(offset.ToString("X2"));
+ },
+ };
+ showFind = new StubCommand {
+ CanExecute = CanAlwaysExecute,
+ Execute = arg => FindControlVisible = (bool)arg,
+ };
clearError = new StubCommand {
CanExecute = arg => showError,
Execute = arg => ErrorMessage = string.Empty,
@@ -209,6 +261,10 @@ namespace HavenSoft.Gen3Hex.ViewModel {
return command;
}
+ private void FindExecuted(string search) {
+
+ }
+
private void RemoveTab(object sender, EventArgs e) {
var tab = (ITabContent)sender;
if (!tabs.Contains(tab)) throw new InvalidOperationException("Cannot remove tab, because tab is not currently in editor.");
diff --git a/Gen3Hex/ViewModel/IViewPort.cs b/Gen3Hex/ViewModel/IViewPort.cs
new file mode 100644
index 00000000..f60ed30c
--- /dev/null
+++ b/Gen3Hex/ViewModel/IViewPort.cs
@@ -0,0 +1,25 @@
+using HavenSoft.Gen3Hex.Model;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.Windows.Input;
+
+namespace HavenSoft.Gen3Hex.ViewModel {
+ public interface IViewPort : ITabContent, INotifyCollectionChanged, INotifyPropertyChanged {
+ int Width { get; set; }
+ int Height { get; set; }
+
+ int MinimumScroll { get; }
+ int ScrollValue { get; }
+ int MaximumScroll { get; }
+ ObservableCollection Headers { get; }
+ ICommand Scroll { get; }
+
+ HexElement this[int x, int y] { get; }
+ bool IsSelected(Point point);
+
+ IReadOnlyList Find(string search);
+ IViewPort CreateChildView(int offset);
+ }
+}
diff --git a/Gen3Hex/ViewModel/ViewPort.cs b/Gen3Hex/ViewModel/ViewPort.cs
index af8393ca..07fccda5 100644
--- a/Gen3Hex/ViewModel/ViewPort.cs
+++ b/Gen3Hex/ViewModel/ViewPort.cs
@@ -12,10 +12,11 @@ using System.Text;
using System.Windows.Input;
namespace HavenSoft.Gen3Hex.ViewModel {
+
///
/// A range of visible data that should be displayed.
///
- public class ViewPort : ViewModelCore, ITabContent, INotifyCollectionChanged {
+ public class ViewPort : ViewModelCore, IViewPort {
private static readonly NotifyCollectionChangedEventArgs ResetArgs = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
private readonly StubCommand
clear = new StubCommand(),
@@ -262,6 +263,15 @@ namespace HavenSoft.Gen3Hex.ViewModel {
for (int i = 0; i < input.Length; i++) Edit(input[i]);
}
+ public IReadOnlyList Find(string search) {
+ // TODO
+ return new int[0];
+ }
+
+ public IViewPort CreateChildView(int offset) {
+ return null;
+ }
+
private void Edit(char input) {
var point = GetEditPoint();
var element = currentView[point.X, point.Y];
diff --git a/HexTests/FindTests.cs b/HexTests/FindTests.cs
index faa2fb46..44014c96 100644
--- a/HexTests/FindTests.cs
+++ b/HexTests/FindTests.cs
@@ -36,7 +36,7 @@ namespace HavenSoft.HexTests {
[Fact]
public void EditorShowsErrorIfNoneFound() {
- var tab = new StubTabContent();
+ var tab = new StubViewPort();
var editor = new EditorViewModel(new StubFileSystem()) { tab };
tab.Find = str => new int[0];
@@ -48,7 +48,7 @@ namespace HavenSoft.HexTests {
[Fact]
public void EditorJumpsToResultIfSingleResult() {
- var tab = new StubTabContent();
+ var tab = new StubViewPort();
var editor = new EditorViewModel(new StubFileSystem()) { tab };
string gotoArg = string.Empty;
@@ -62,7 +62,7 @@ namespace HavenSoft.HexTests {
[Fact]
public void EditorOpensHelperTabIfMultipleResult() {
- var tab = new StubTabContent();
+ var tab = new StubViewPort();
var editor = new EditorViewModel(new StubFileSystem()) { tab };
var count = 0;
@@ -82,7 +82,7 @@ namespace HavenSoft.HexTests {
[Fact]
public void EditorHasShortcutsToGetPreviousOrNextFindResult() {
- var tab = new StubTabContent();
+ var tab = new StubViewPort();
var editor = new EditorViewModel(new StubFileSystem()) { tab };
int gotoCount = 0;
diff --git a/HexTests/HexTests.csproj b/HexTests/HexTests.csproj
index de75afba..4575027c 100644
--- a/HexTests/HexTests.csproj
+++ b/HexTests/HexTests.csproj
@@ -64,6 +64,7 @@
+
@@ -105,7 +106,7 @@
if not exist $(ProjectDir)generatedCode mkdir $(ProjectDir)generatedCode
-$(SolutionDir)packages\HavenSoft.AutoImplement.1.0.1\AutoImplement $(SolutionDir)Gen3Hex\$(OutDir)Gen3Hex.exe ITabContent IFileSystem
+$(SolutionDir)packages\HavenSoft.AutoImplement.1.0.1\AutoImplement $(SolutionDir)Gen3Hex\$(OutDir)Gen3Hex.exe ITabContent IFileSystem IViewPort
move /Y StubTabContent.cs $(ProjectDir)generatedCode
move /Y StubFileSystem.cs $(ProjectDir)generatedCode
diff --git a/HexTests/generatedCode/StubViewPort.cs b/HexTests/generatedCode/StubViewPort.cs
new file mode 100644
index 00000000..50bd0d29
--- /dev/null
+++ b/HexTests/generatedCode/StubViewPort.cs
@@ -0,0 +1,286 @@
+// this file was created by AutoImplement
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.Delegation;
+
+namespace HavenSoft.Gen3Hex.ViewModel
+{
+ public class StubViewPort : IViewPort
+ {
+ public Func IsSelected { get; set; }
+
+ bool IViewPort.IsSelected(HavenSoft.Gen3Hex.Model.Point point)
+ {
+ if (this.IsSelected != null)
+ {
+ return this.IsSelected(point);
+ }
+ else
+ {
+ return default(bool);
+ }
+ }
+
+ public Func> Find { get; set; }
+
+ System.Collections.Generic.IReadOnlyList IViewPort.Find(string search)
+ {
+ if (this.Find != null)
+ {
+ return this.Find(search);
+ }
+ else
+ {
+ return default(System.Collections.Generic.IReadOnlyList);
+ }
+ }
+
+ public Func CreateChildView { get; set; }
+
+ IViewPort IViewPort.CreateChildView(int offset)
+ {
+ if (this.CreateChildView != null)
+ {
+ return this.CreateChildView(offset);
+ }
+ else
+ {
+ return default(IViewPort);
+ }
+ }
+
+ public PropertyImplementation Width = new PropertyImplementation();
+
+ int IViewPort.Width
+ {
+ get
+ {
+ return this.Width.get();
+ }
+ set
+ {
+ this.Width.set(value);
+ }
+ }
+ public PropertyImplementation Height = new PropertyImplementation();
+
+ int IViewPort.Height
+ {
+ get
+ {
+ return this.Height.get();
+ }
+ set
+ {
+ this.Height.set(value);
+ }
+ }
+ public PropertyImplementation MinimumScroll = new PropertyImplementation();
+
+ int IViewPort.MinimumScroll
+ {
+ get
+ {
+ return this.MinimumScroll.get();
+ }
+ }
+ public PropertyImplementation ScrollValue = new PropertyImplementation();
+
+ int IViewPort.ScrollValue
+ {
+ get
+ {
+ return this.ScrollValue.get();
+ }
+ }
+ public PropertyImplementation MaximumScroll = new PropertyImplementation();
+
+ int IViewPort.MaximumScroll
+ {
+ get
+ {
+ return this.MaximumScroll.get();
+ }
+ }
+ public PropertyImplementation> Headers = new PropertyImplementation>();
+
+ System.Collections.ObjectModel.ObservableCollection IViewPort.Headers
+ {
+ get
+ {
+ return this.Headers.get();
+ }
+ }
+ public PropertyImplementation Scroll = new PropertyImplementation();
+
+ System.Windows.Input.ICommand IViewPort.Scroll
+ {
+ get
+ {
+ return this.Scroll.get();
+ }
+ }
+ public Func get_Item = (x, y) => default(HexElement);
+
+ HexElement IViewPort.this[int x, int y]
+ {
+ get
+ {
+ return get_Item(x, y);
+ }
+ }
+ public PropertyImplementation Name = new PropertyImplementation();
+
+ string ITabContent.Name
+ {
+ get
+ {
+ return this.Name.get();
+ }
+ }
+ public PropertyImplementation Save = new PropertyImplementation();
+
+ System.Windows.Input.ICommand ITabContent.Save
+ {
+ get
+ {
+ return this.Save.get();
+ }
+ }
+ public PropertyImplementation SaveAs = new PropertyImplementation();
+
+ System.Windows.Input.ICommand ITabContent.SaveAs
+ {
+ get
+ {
+ return this.SaveAs.get();
+ }
+ }
+ public PropertyImplementation Undo = new PropertyImplementation();
+
+ System.Windows.Input.ICommand ITabContent.Undo
+ {
+ get
+ {
+ return this.Undo.get();
+ }
+ }
+ public PropertyImplementation Redo = new PropertyImplementation();
+
+ System.Windows.Input.ICommand ITabContent.Redo
+ {
+ get
+ {
+ return this.Redo.get();
+ }
+ }
+ public PropertyImplementation Copy = new PropertyImplementation();
+
+ System.Windows.Input.ICommand ITabContent.Copy
+ {
+ get
+ {
+ return this.Copy.get();
+ }
+ }
+ public PropertyImplementation Clear = new PropertyImplementation();
+
+ System.Windows.Input.ICommand ITabContent.Clear
+ {
+ get
+ {
+ return this.Clear.get();
+ }
+ }
+ public PropertyImplementation Goto = new PropertyImplementation();
+
+ System.Windows.Input.ICommand ITabContent.Goto
+ {
+ get
+ {
+ return this.Goto.get();
+ }
+ }
+ public PropertyImplementation Back = new PropertyImplementation();
+
+ System.Windows.Input.ICommand ITabContent.Back
+ {
+ get
+ {
+ return this.Back.get();
+ }
+ }
+ public PropertyImplementation Forward = new PropertyImplementation();
+
+ System.Windows.Input.ICommand ITabContent.Forward
+ {
+ get
+ {
+ return this.Forward.get();
+ }
+ }
+ public PropertyImplementation Close = new PropertyImplementation();
+
+ System.Windows.Input.ICommand ITabContent.Close
+ {
+ get
+ {
+ return this.Close.get();
+ }
+ }
+ public EventImplementation OnError = new EventImplementation();
+
+ event System.EventHandler ITabContent.OnError
+ {
+ add
+ {
+ OnError.add(new EventHandler(value));
+ }
+ remove
+ {
+ OnError.remove(new EventHandler(value));
+ }
+ }
+ public EventImplementation Closed = new EventImplementation();
+
+ event System.EventHandler ITabContent.Closed
+ {
+ add
+ {
+ Closed.add(new EventHandler(value));
+ }
+ remove
+ {
+ Closed.remove(new EventHandler(value));
+ }
+ }
+ public EventImplementation CollectionChanged = new EventImplementation();
+
+ event NotifyCollectionChangedEventHandler INotifyCollectionChanged.CollectionChanged
+ {
+ add
+ {
+ CollectionChanged.add(new EventHandler(value));
+ }
+ remove
+ {
+ CollectionChanged.remove(new EventHandler(value));
+ }
+ }
+ public EventImplementation PropertyChanged = new EventImplementation();
+
+ event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
+ {
+ add
+ {
+ PropertyChanged.add(new EventHandler(value));
+ }
+ remove
+ {
+ PropertyChanged.remove(new EventHandler(value));
+ }
+ }
+ }
+}