protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e) { if (changeGroup != null && _isChangeGroupOpen) { changeGroup.Commit(); _isChangeGroupOpen = false; } base.OnLostKeyboardFocus(e); }
void drag_Completed(DragListener drag) { if (operation != null) { if (drag.IsCanceled) { operation.Abort(); } else { operation.Commit(); } operation = null; } else { if (drag.IsCanceled) { changeGroup.Abort(); } else { changeGroup.Commit(); } changeGroup = null; } _isResizing = false; HideSizeAndShowHandles(); }
public void UndoRedoChangeGroupTest() { DesignItem button = CreateCanvasContext("<Button/>"); UndoService s = button.Context.Services.GetService <UndoService>(); Assert.IsFalse(s.CanUndo); Assert.IsFalse(s.CanRedo); using (ChangeGroup g = button.OpenGroup("Resize")) { button.Properties["Width"].SetValue(100.0); button.Properties["Height"].SetValue(200.0); g.Commit(); } Assert.IsTrue(s.CanUndo); Assert.IsFalse(s.CanRedo); AssertCanvasDesignerOutput(@"<Button Width=""100"" Height=""200"" />", button.Context); s.Undo(); Assert.IsFalse(s.CanUndo); Assert.IsTrue(s.CanRedo); AssertCanvasDesignerOutput(@"<Button />", button.Context); s.Redo(); Assert.IsTrue(s.CanUndo); Assert.IsFalse(s.CanRedo); AssertCanvasDesignerOutput(@"<Button Width=""100"" Height=""200"" />", button.Context); AssertLog(""); }
protected override void OnMouseDoubleClick(object sender, MouseButtonEventArgs e) { base.OnMouseDoubleClick(sender, e); if (newLine.View is Polyline) { ((Polyline)newLine.View).Points.RemoveAt(((Polyline)newLine.View).Points.Count - 1); newLine.Properties[Polyline.PointsProperty] .SetValue(string.Join(",", ((Polyline)newLine.View).Points)); } else { ((Polygon)newLine.View).Points.RemoveAt(((Polygon)newLine.View).Points.Count - 1); newLine.Properties[Polygon.PointsProperty] .SetValue(string.Join(",", ((Polygon)newLine.View).Points)); } if (changeGroup != null) { changeGroup.Commit(); changeGroup = null; } Stop(); }
protected override void OnMouseUp(object sender, MouseButtonEventArgs e) { if (hasDragStarted) { if (operation != null) { operation.Commit(); operation = null; } } else { CreateComponentTool.AddItemWithDefaultSize(container, createdItem, e.GetPosition(positionRelativeTo)); } if (changeGroup != null) { changeGroup.Commit(); changeGroup = null; } if (designPanel.Context.Services.Component is XamlComponentService) { ((XamlComponentService)designPanel.Context.Services.Component).RaiseComponentRegisteredAndAddedToContainer(createdItem); } base.OnMouseUp(sender, e); }
private void ColorEditorPopup_Closed(object sender, EventArgs e) { if (_changeGroup != null) { _changeGroup.Commit(); _changeGroup = null; } }
protected override void OnMouseUp(MouseButtonEventArgs e) { if (activeChangeGroup != null) { activeChangeGroup.Commit(); activeChangeGroup = null; } Stop(); }
protected override void OnMouseUp(object sender, MouseButtonEventArgs e) { l.DragListener.ExternalStop(); if (changeGroup != null) { changeGroup.Commit(); changeGroup = null; } base.OnMouseUp(sender, e); }
/// <summary> /// Change is committed if the user releases the Escape Key. /// </summary> /// <param name="e"></param> protected override void OnKeyUp(KeyEventArgs e) { base.OnKeyUp(e); if (e.KeyboardDevice.Modifiers != ModifierKeys.Shift) { switch (e.Key) { case Key.Enter: // Commit the changes to DOM. if (designItem.Properties[Control.FontFamilyProperty].ValueOnInstance != editor.FontFamily) { designItem.Properties[Control.FontFamilyProperty].SetValue(editor.FontFamily); } if ((double)designItem.Properties[Control.FontSizeProperty].ValueOnInstance != editor.FontSize) { designItem.Properties[Control.FontSizeProperty].SetValue(editor.FontSize); } if ((FontStretch)designItem.Properties[Control.FontStretchProperty].ValueOnInstance != editor.FontStretch) { designItem.Properties[Control.FontStretchProperty].SetValue(editor.FontStretch); } if ((FontStyle)designItem.Properties[Control.FontStyleProperty].ValueOnInstance != editor.FontStyle) { designItem.Properties[Control.FontStyleProperty].SetValue(editor.FontStyle); } if ((FontWeight)designItem.Properties[Control.FontWeightProperty].ValueOnInstance != editor.FontWeight) { designItem.Properties[Control.FontWeightProperty].SetValue(editor.FontWeight); } if (changeGroup != null && _isChangeGroupOpen) { FormatedTextEditor.SetTextBlockTextFromRichTextBlox(this.designItem, editor); changeGroup.Commit(); _isChangeGroupOpen = false; } changeGroup = null; this.Visibility = Visibility.Hidden; this.designItem.ReapplyAllExtensions(); ((TextBlock)designItem.Component).Visibility = Visibility.Visible; break; case Key.Escape: AbortEditing(); break; } } else if (e.Key == Key.Enter) { editor.Selection.Text += Environment.NewLine; } }
/// <summary> /// Change is committed if the user releases the Escape Key. /// </summary> /// <param name="e"></param> protected override void OnKeyUp(KeyEventArgs e) { base.OnKeyUp(e); if (e.KeyboardDevice.Modifiers != ModifierKeys.Shift) { switch (e.Key) { case Key.Enter: // Commit the changes to DOM. if (property != null) { designItem.Properties[property].SetValue(Bind); } if (designItem.Properties[Control.FontFamilyProperty].ValueOnInstance != editor.FontFamily) { designItem.Properties[Control.FontFamilyProperty].SetValue(editor.FontFamily); } if ((double)designItem.Properties[Control.FontSizeProperty].ValueOnInstance != editor.FontSize) { designItem.Properties[Control.FontSizeProperty].SetValue(editor.FontSize); } if ((FontStretch)designItem.Properties[Control.FontStretchProperty].ValueOnInstance != editor.FontStretch) { designItem.Properties[Control.FontStretchProperty].SetValue(editor.FontStretch); } if ((FontStyle)designItem.Properties[Control.FontStyleProperty].ValueOnInstance != editor.FontStyle) { designItem.Properties[Control.FontStyleProperty].SetValue(editor.FontStyle); } if ((FontWeight)designItem.Properties[Control.FontWeightProperty].ValueOnInstance != editor.FontWeight) { designItem.Properties[Control.FontWeightProperty].SetValue(editor.FontWeight); } if (changeGroup != null && _isChangeGroupOpen) { changeGroup.Commit(); _isChangeGroupOpen = false; } changeGroup = null; this.Visibility = Visibility.Hidden; textBlock.Visibility = Visibility.Visible; break; case Key.Escape: AbortEditing(); break; } } else if (e.Key == Key.Enter) { editor.Text.Insert(editor.CaretIndex, Environment.NewLine); } }
public void UndoRedoInputBindings() { const string originalXaml = "<TextBlock Text=\"My text\" />"; DesignItem textBlock = CreateCanvasContext(originalXaml); UndoService s = textBlock.Context.Services.GetService <UndoService>(); IComponentService component = textBlock.Context.Services.Component; Assert.IsFalse(s.CanUndo); Assert.IsFalse(s.CanRedo); DesignItemProperty inputbinding = textBlock.Properties["InputBindings"]; Assert.IsTrue(inputbinding.IsCollection); const string expectedXaml = @"<TextBlock Text=""My text""> <TextBlock.InputBindings> <MouseBinding Gesture=""LeftDoubleClick"" Command=""ApplicationCommands.New"" /> </TextBlock.InputBindings> </TextBlock>"; using (ChangeGroup changeGroup = textBlock.Context.OpenGroup("", new[] { textBlock })) { DesignItem di = component.RegisterComponentForDesigner(new System.Windows.Input.MouseBinding()); di.Properties["Gesture"].SetValue(System.Windows.Input.MouseAction.LeftDoubleClick); di.Properties["Command"].SetValue("ApplicationCommands.New"); inputbinding.CollectionElements.Add(di); changeGroup.Commit(); } Assert.IsTrue(s.CanUndo); Assert.IsFalse(s.CanRedo); AssertCanvasDesignerOutput(expectedXaml, textBlock.Context); inputbinding = textBlock.Properties["InputBindings"]; Assert.IsTrue(((System.Windows.Input.InputBindingCollection)inputbinding.ValueOnInstance).Count == inputbinding.CollectionElements.Count); s.Undo(); Assert.IsFalse(s.CanUndo); Assert.IsTrue(s.CanRedo); AssertCanvasDesignerOutput(originalXaml, textBlock.Context); s.Redo(); Assert.IsTrue(s.CanUndo); Assert.IsFalse(s.CanRedo); AssertCanvasDesignerOutput(expectedXaml, textBlock.Context); Assert.IsTrue(((System.Windows.Input.InputBindingCollection)inputbinding.ValueOnInstance).Count == inputbinding.CollectionElements.Count); AssertLog(""); }
protected override void OnMouseDoubleClick(object sender, MouseButtonEventArgs e) { base.OnMouseDoubleClick(sender, e); figure.Segments.RemoveAt(figure.Segments.Count - 1); geometry.Properties[PathGeometry.FiguresProperty].SetValue(figure.ToString()); if (changeGroup != null) { changeGroup.Commit(); changeGroup = null; } Stop(); }
protected override void OnMouseDoubleClick(object sender, MouseButtonEventArgs e) { base.OnMouseDoubleClick(sender, e); figure.Segments.RemoveAt(figure.Segments.Count - 1); var prop = geometry.Properties[PathGeometry.FiguresProperty]; prop.SetValue(prop.TypeConverter.ConvertToInvariantString(figure)); if (changeGroup != null) { changeGroup.Commit(); changeGroup = null; } Stop(); }
void designPanel_Drop(object sender, DragEventArgs e) { try { if (moveLogic != null) { moveLogic.Stop(); if (moveLogic.ClickedOn.Services.Tool.CurrentTool is CreateComponentTool) { moveLogic.ClickedOn.Services.Tool.CurrentTool = moveLogic.ClickedOn.Services.Tool.PointerTool; } moveLogic.DesignPanel.IsAdornerLayerHitTestVisible = true; moveLogic = null; changeGroup.Commit(); } } catch (Exception x) { DragDropExceptionHandler.RaiseUnhandledException(x); } }
protected override void OnMouseUp(object sender, MouseButtonEventArgs e) { if (hasDragStarted) { if (operation != null) { operation.Commit(); operation = null; } } else { CreateComponentTool.AddItemWithDefaultSize(container, createdItem, e.GetPosition(positionRelativeTo)); } if (changeGroup != null) { changeGroup.Commit(); changeGroup = null; } base.OnMouseUp(sender, e); }
protected override void OnDragCompleted() { group.Commit(); }
void UndoRedoListInternal(bool useExplicitList) { DesignItem button = CreateCanvasContext("<Button/>"); UndoService s = button.Context.Services.GetService <UndoService>(); IComponentService component = button.Context.Services.Component; string expectedXamlWithList; DesignItemProperty otherListProp; Assert.IsFalse(s.CanUndo); Assert.IsFalse(s.CanRedo); using (ChangeGroup g = button.OpenGroup("UndoRedoListInternal test")) { DesignItem containerItem = component.RegisterComponentForDesigner(new ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassContainer()); otherListProp = containerItem.Properties["OtherList"]; if (useExplicitList) { otherListProp.SetValue(new ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassList()); expectedXamlWithList = @"<Button> <Button.Tag> <Controls0:ExampleClassContainer> <Controls0:ExampleClassContainer.OtherList> <Controls0:ExampleClassList> <Controls0:ExampleClass StringProp=""String value"" /> </Controls0:ExampleClassList> </Controls0:ExampleClassContainer.OtherList> </Controls0:ExampleClassContainer> </Button.Tag> </Button>"; } else { expectedXamlWithList = @"<Button> <Button.Tag> <Controls0:ExampleClassContainer> <Controls0:ExampleClassContainer.OtherList> <Controls0:ExampleClass StringProp=""String value"" /> </Controls0:ExampleClassContainer.OtherList> </Controls0:ExampleClassContainer> </Button.Tag> </Button>"; } DesignItem exampleClassItem = component.RegisterComponentForDesigner(new ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClass()); exampleClassItem.Properties["StringProp"].SetValue("String value"); otherListProp.CollectionElements.Add(exampleClassItem); button.Properties["Tag"].SetValue(containerItem); g.Commit(); } Assert.IsTrue(s.CanUndo); Assert.IsFalse(s.CanRedo); AssertCanvasDesignerOutput(expectedXamlWithList, button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); otherListProp = button.Properties["Tag"].Value.Properties["OtherList"]; Assert.IsTrue(((ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassList)otherListProp.ValueOnInstance).Count == otherListProp.CollectionElements.Count); s.Undo(); Assert.IsFalse(s.CanUndo); Assert.IsTrue(s.CanRedo); AssertCanvasDesignerOutput("<Button>\n</Button>", button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); s.Redo(); Assert.IsTrue(s.CanUndo); Assert.IsFalse(s.CanRedo); AssertCanvasDesignerOutput(expectedXamlWithList, button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); otherListProp = button.Properties["Tag"].Value.Properties["OtherList"]; Assert.IsTrue(((ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassList)otherListProp.ValueOnInstance).Count == otherListProp.CollectionElements.Count); AssertLog(""); }
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); e.Handled = true; Focus(); adornerPanel.Children.Remove(previewAdorner); if (orientation == Orientation.Vertical) { double insertionPosition = e.GetPosition(this).Y; DesignItemProperty rowCollection = gridItem.Properties["RowDefinitions"]; DesignItem currentRow = null; using (ChangeGroup changeGroup = gridItem.OpenGroup("Split grid row")) { if (rowCollection.CollectionElements.Count == 0) { DesignItem firstRow = gridItem.Services.Component.RegisterComponentForDesigner(new RowDefinition()); rowCollection.CollectionElements.Add(firstRow); grid.UpdateLayout(); // let WPF assign firstRow.ActualHeight currentRow = firstRow; } else { RowDefinition current = grid.RowDefinitions .FirstOrDefault(r => insertionPosition >= r.Offset && insertionPosition <= (r.Offset + r.ActualHeight)); if (current != null) { currentRow = gridItem.Services.Component.GetDesignItem(current); } } if (currentRow == null) { currentRow = gridItem.Services.Component.GetDesignItem(grid.RowDefinitions.Last()); } unitSelector.SelectedItem = currentRow; for (int i = 0; i < grid.RowDefinitions.Count; i++) { RowDefinition row = grid.RowDefinitions[i]; if (row.Offset > insertionPosition) { continue; } if (row.Offset + row.ActualHeight < insertionPosition) { continue; } // split row GridLength oldLength = (GridLength)row.GetValue(RowDefinition.HeightProperty); GridLength newLength1, newLength2; SplitLength(oldLength, insertionPosition - row.Offset, row.ActualHeight, out newLength1, out newLength2); DesignItem newRowDefinition = gridItem.Services.Component.RegisterComponentForDesigner(new RowDefinition()); rowCollection.CollectionElements.Insert(i + 1, newRowDefinition); rowCollection.CollectionElements[i].Properties[RowDefinition.HeightProperty].SetValue(newLength1); newRowDefinition.Properties[RowDefinition.HeightProperty].SetValue(newLength2); grid.UpdateLayout(); FixIndicesAfterSplit(i, Grid.RowProperty, Grid.RowSpanProperty, insertionPosition); grid.UpdateLayout(); changeGroup.Commit(); break; } } } else { double insertionPosition = e.GetPosition(this).X; DesignItemProperty columnCollection = gridItem.Properties["ColumnDefinitions"]; DesignItem currentColumn = null; using (ChangeGroup changeGroup = gridItem.OpenGroup("Split grid column")) { if (columnCollection.CollectionElements.Count == 0) { DesignItem firstColumn = gridItem.Services.Component.RegisterComponentForDesigner(new ColumnDefinition()); columnCollection.CollectionElements.Add(firstColumn); grid.UpdateLayout(); // let WPF assign firstColumn.ActualWidth currentColumn = firstColumn; } else { ColumnDefinition current = grid.ColumnDefinitions .FirstOrDefault(r => insertionPosition >= r.Offset && insertionPosition <= (r.Offset + r.ActualWidth)); if (current != null) { currentColumn = gridItem.Services.Component.GetDesignItem(current); } } if (currentColumn == null) { currentColumn = gridItem.Services.Component.GetDesignItem(grid.ColumnDefinitions.Last()); } unitSelector.SelectedItem = currentColumn; for (int i = 0; i < grid.ColumnDefinitions.Count; i++) { ColumnDefinition column = grid.ColumnDefinitions[i]; if (column.Offset > insertionPosition) { continue; } if (column.Offset + column.ActualWidth < insertionPosition) { continue; } // split column GridLength oldLength = (GridLength)column.GetValue(ColumnDefinition.WidthProperty); GridLength newLength1, newLength2; SplitLength(oldLength, insertionPosition - column.Offset, column.ActualWidth, out newLength1, out newLength2); DesignItem newColumnDefinition = gridItem.Services.Component.RegisterComponentForDesigner(new ColumnDefinition()); columnCollection.CollectionElements.Insert(i + 1, newColumnDefinition); columnCollection.CollectionElements[i].Properties[ColumnDefinition.WidthProperty].SetValue(newLength1); newColumnDefinition.Properties[ColumnDefinition.WidthProperty].SetValue(newLength2); grid.UpdateLayout(); FixIndicesAfterSplit(i, Grid.ColumnProperty, Grid.ColumnSpanProperty, insertionPosition); changeGroup.Commit(); grid.UpdateLayout(); break; } } } InvalidateVisual(); }
void UndoRedoDictionaryInternal(bool useExplicitDictionary) { const string originalXaml = "<Button />"; DesignItem button = CreateCanvasContext(originalXaml); UndoService s = button.Context.Services.GetService <UndoService>(); IComponentService component = button.Context.Services.Component; string expectedXamlWithDictionary; DesignItemProperty dictionaryProp; Assert.IsFalse(s.CanUndo); Assert.IsFalse(s.CanRedo); using (ChangeGroup g = button.OpenGroup("UndoRedoDictionaryInternal test")) { DesignItem containerItem = component.RegisterComponentForDesigner(new ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassContainer()); dictionaryProp = containerItem.Properties["Dictionary"]; if (useExplicitDictionary) { dictionaryProp.SetValue(new ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassDictionary()); expectedXamlWithDictionary = @"<Button> <Button.Tag> <Controls0:ExampleClassContainer> <Controls0:ExampleClassContainer.Dictionary> <Controls0:ExampleClassDictionary> <Controls0:ExampleClass x:Key=""testKey"" StringProp=""String value"" /> </Controls0:ExampleClassDictionary> </Controls0:ExampleClassContainer.Dictionary> </Controls0:ExampleClassContainer> </Button.Tag> </Button>"; } else { expectedXamlWithDictionary = @"<Button> <Button.Tag> <Controls0:ExampleClassContainer> <Controls0:ExampleClassContainer.Dictionary> <Controls0:ExampleClass x:Key=""testKey"" StringProp=""String value"" /> </Controls0:ExampleClassContainer.Dictionary> </Controls0:ExampleClassContainer> </Button.Tag> </Button>"; } DesignItem exampleClassItem = component.RegisterComponentForDesigner(new ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClass()); exampleClassItem.Key = "testKey"; exampleClassItem.Properties["StringProp"].SetValue("String value"); dictionaryProp.CollectionElements.Add(exampleClassItem); button.Properties["Tag"].SetValue(containerItem); g.Commit(); } Assert.IsTrue(s.CanUndo); Assert.IsFalse(s.CanRedo); AssertCanvasDesignerOutput(expectedXamlWithDictionary, button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); dictionaryProp = button.Properties["Tag"].Value.Properties["Dictionary"]; Assert.IsTrue(((ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassDictionary)dictionaryProp.ValueOnInstance).Count == dictionaryProp.CollectionElements.Count); s.Undo(); Assert.IsFalse(s.CanUndo); Assert.IsTrue(s.CanRedo); AssertCanvasDesignerOutput(originalXaml, button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); s.Redo(); Assert.IsTrue(s.CanUndo); Assert.IsFalse(s.CanRedo); AssertCanvasDesignerOutput(expectedXamlWithDictionary, button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); dictionaryProp = button.Properties["Tag"].Value.Properties["Dictionary"]; Assert.IsTrue(((ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassDictionary)dictionaryProp.ValueOnInstance).Count == dictionaryProp.CollectionElements.Count); AssertLog(""); }
void UndoRedoInputBindingsRemoveClearResetInternal(bool remove, bool clear, bool reset) { const string originalXaml = "<TextBlock Text=\"My text\" />"; DesignItem textBlock = CreateCanvasContext(originalXaml); UndoService s = textBlock.Context.Services.GetService <UndoService>(); IComponentService component = textBlock.Context.Services.Component; Assert.IsFalse(s.CanUndo); Assert.IsFalse(s.CanRedo); DesignItemProperty inputbinding = textBlock.Properties["InputBindings"]; Assert.IsTrue(inputbinding.IsCollection); const string expectedXaml = @"<TextBlock Text=""My text"" Cursor=""Hand""> <TextBlock.InputBindings> <MouseBinding Gesture=""LeftDoubleClick"" Command=""ApplicationCommands.New"" /> </TextBlock.InputBindings> </TextBlock>"; using (ChangeGroup changeGroup = textBlock.Context.OpenGroup("", new[] { textBlock })) { DesignItem di = component.RegisterComponentForDesigner(new System.Windows.Input.MouseBinding()); di.Properties["Gesture"].SetValue(System.Windows.Input.MouseAction.LeftDoubleClick); di.Properties["Command"].SetValue("ApplicationCommands.New"); inputbinding.CollectionElements.Add(di); textBlock.Properties["Cursor"].SetValue(System.Windows.Input.Cursors.Hand); changeGroup.Commit(); } Assert.IsTrue(s.CanUndo); Assert.IsFalse(s.CanRedo); AssertCanvasDesignerOutput(expectedXaml, textBlock.Context); using (ChangeGroup changeGroup = textBlock.Context.OpenGroup("", new[] { textBlock })) { DesignItem di = inputbinding.CollectionElements.First(); // Remove, Clear, Reset combination caused exception at first Undo after this group commit before the issue was fixed if (remove) { inputbinding.CollectionElements.Remove(di); } if (clear) { inputbinding.CollectionElements.Clear(); } if (reset) { inputbinding.Reset(); } di = component.RegisterComponentForDesigner(new System.Windows.Input.MouseBinding()); di.Properties["Gesture"].SetValue(System.Windows.Input.MouseAction.LeftDoubleClick); di.Properties["Command"].SetValue("ApplicationCommands.New"); inputbinding.CollectionElements.Add(di); textBlock.Properties["Cursor"].SetValue(System.Windows.Input.Cursors.Hand); changeGroup.Commit(); } s.Undo(); s.Undo(); Assert.IsFalse(s.CanUndo); Assert.IsTrue(s.CanRedo); AssertCanvasDesignerOutput(originalXaml, textBlock.Context); s.Redo(); s.Redo(); Assert.IsTrue(s.CanUndo); Assert.IsFalse(s.CanRedo); AssertCanvasDesignerOutput(expectedXaml, textBlock.Context); Assert.IsTrue(((System.Windows.Input.InputBindingCollection)inputbinding.ValueOnInstance).Count == inputbinding.CollectionElements.Count); AssertLog(""); }