UIElementPropertyUndoUnit.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Documents / UIElementPropertyUndoUnit.cs / 1305600 / UIElementPropertyUndoUnit.cs

                            //---------------------------------------------------------------------------- 
//
// File: UIElementPropertyUndoUnit.cs
//
// Description: Undo unit for property sets on UIElement. 
// It is created for:
//  1. FlowDirectionProperty sets on a TextEditor's UI scope element. 
//  2. HorizontalAlignmentProperty sets on UIElement child of BlockUIContainer. 
//
// History: 
// 01/13/2006 : pjoshi - Branched from FlowDirectionUndoUnit.cs
//
//---------------------------------------------------------------------------
 
using System;
using System.Windows; 
using MS.Internal; 
using MS.Internal.Documents;
 
namespace System.Windows.Documents
{
    // 1. Undo unit for FlowDirectionProperty sets on a TextEditor's UI scope element.
    // 
    // The TextEditor lets users configure the FlowDirection of text dynamically
    // even when running on TextBoxes (TextEditor.AcceptsRichContent == false). 
    // In this case, there's no TextElement to hang property values on, so we must 
    // resort to assigning values directly to the TextEditor's UiScope, which is
    // not covered by the TextContainer's undo infrastructure. 
    //
    // This class encapsulates an undo unit used to track FlowDirection changes on
    // plain text documents.
    // 
    // 2. Undo unit for HorizontalAlignmentProperty sets on UIElement child of BlockUIContainer.
    // 
    // When applying TextAlignment property to BlockUIContainer elements in rich text documents, 
    // text alignment must be translated into HorizontalAlignment of its child UIElement.
    // We must assign this property value directly to the embedded UIElement. 
    // Since TextEditor's undo mechanism for property changes on TextElements in the tree relies
    // on the OnPropertyChanged event listener, it is unable to track this property change.
    // Also, it is infeasible to have a OnPropertyChanged listener for all UIElements.
    // So we resort to explicitly adding this special undo unit in such situation. 
    //
    internal class UIElementPropertyUndoUnit : IUndoUnit 
    { 
        //-----------------------------------------------------
        // 
        //  Constructors
        //
        //-----------------------------------------------------
 
        #region Constructors
 
        // Create a new undo unit instance. 
        private UIElementPropertyUndoUnit(UIElement uiElement, DependencyProperty property, object oldValue)
        { 
            _uiElement = uiElement;
            _property = property;
            _oldValue = oldValue;
        } 

        #endregion Constructors 
 
        //------------------------------------------------------
        // 
        //  Public Methods
        //
        //-----------------------------------------------------
 
        #region Public Methods
 
        // Called by the undo manager.  Restores tree state to its condition 
        // when the unit was created.
        public void Do() 
        {
            if (_oldValue != DependencyProperty.UnsetValue)
            {
                _uiElement.SetValue(_property, _oldValue); 
            }
            else 
            { 
                _uiElement.ClearValue(_property);
            } 
        }

        // Called by the undo manager.
        public bool Merge(IUndoUnit unit) 
        {
            Invariant.Assert(unit != null); 
            return false; 
        }
 
        #endregion Public Methods

        //------------------------------------------------------
        // 
        //  Internal Methods
        // 
        //------------------------------------------------------ 

        #region Internal Methods 

        // Note that following strongly typed overloads of Add are meant to restrict the usage of UIElementPropertyUndoUnit
        // for tracking changes to only a limited set of properties of UIElements.
        // In general, it is not safe to keep a reference to the original property value, however for enum types, it is safe to do so. 

        // Add a new UIElementPropertyUndoUnit to the undo stack for HorizontalAlignment property. 
        internal static void Add(ITextContainer textContainer, UIElement uiElement, DependencyProperty property, HorizontalAlignment newValue) 
        {
            AddPrivate(textContainer, uiElement, property, newValue); 
        }

        // Add a new UIElementPropertyUndoUnit to the undo stack for FlowDirection property.
        internal static void Add(ITextContainer textContainer, UIElement uiElement, DependencyProperty property, FlowDirection newValue) 
        {
            AddPrivate(textContainer, uiElement, property, newValue); 
        } 

        #endregion Internal Methods 

        //-----------------------------------------------------
        //
        //  Privte Methods 
        //
        //------------------------------------------------------ 
 
        #region Private Methods
 
        // Private helper that adds a new UIElementPropertyUndoUnit to the undo stack.
        private static void AddPrivate(ITextContainer textContainer, UIElement uiElement, DependencyProperty property, object newValue)
        {
            UndoManager undoManager = TextTreeUndo.GetOrClearUndoManager(textContainer); 

            if (undoManager == null) 
            { 
                return;
            } 

            object currentValue = uiElement.ReadLocalValue(property);

            if (currentValue is Expression) 
            {
                // Can't undo when old value is an expression, so clear the stack. 
                if (undoManager.IsEnabled) 
                {
                    undoManager.Clear(); 
                }
                return;
            }
 
            if (currentValue.Equals(newValue))
            { 
                // No property change. 
                return;
            } 

            undoManager.Add(new UIElementPropertyUndoUnit(uiElement, property, currentValue));
        }
 
        #endregion Private Methods
 
        //----------------------------------------------------- 
        //
        //  Private Fields 
        //
        //-----------------------------------------------------

        #region Private Fields 

        // UIElement associated with this undo unit. 
        private readonly UIElement _uiElement; 

        // DependencyProperty of the UIElement associated with this undo unit. 
        private readonly DependencyProperty _property;

        // Original property value.
        private readonly object _oldValue; 

        #endregion Private Fields 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// File: UIElementPropertyUndoUnit.cs
//
// Description: Undo unit for property sets on UIElement. 
// It is created for:
//  1. FlowDirectionProperty sets on a TextEditor's UI scope element. 
//  2. HorizontalAlignmentProperty sets on UIElement child of BlockUIContainer. 
//
// History: 
// 01/13/2006 : pjoshi - Branched from FlowDirectionUndoUnit.cs
//
//---------------------------------------------------------------------------
 
using System;
using System.Windows; 
using MS.Internal; 
using MS.Internal.Documents;
 
namespace System.Windows.Documents
{
    // 1. Undo unit for FlowDirectionProperty sets on a TextEditor's UI scope element.
    // 
    // The TextEditor lets users configure the FlowDirection of text dynamically
    // even when running on TextBoxes (TextEditor.AcceptsRichContent == false). 
    // In this case, there's no TextElement to hang property values on, so we must 
    // resort to assigning values directly to the TextEditor's UiScope, which is
    // not covered by the TextContainer's undo infrastructure. 
    //
    // This class encapsulates an undo unit used to track FlowDirection changes on
    // plain text documents.
    // 
    // 2. Undo unit for HorizontalAlignmentProperty sets on UIElement child of BlockUIContainer.
    // 
    // When applying TextAlignment property to BlockUIContainer elements in rich text documents, 
    // text alignment must be translated into HorizontalAlignment of its child UIElement.
    // We must assign this property value directly to the embedded UIElement. 
    // Since TextEditor's undo mechanism for property changes on TextElements in the tree relies
    // on the OnPropertyChanged event listener, it is unable to track this property change.
    // Also, it is infeasible to have a OnPropertyChanged listener for all UIElements.
    // So we resort to explicitly adding this special undo unit in such situation. 
    //
    internal class UIElementPropertyUndoUnit : IUndoUnit 
    { 
        //-----------------------------------------------------
        // 
        //  Constructors
        //
        //-----------------------------------------------------
 
        #region Constructors
 
        // Create a new undo unit instance. 
        private UIElementPropertyUndoUnit(UIElement uiElement, DependencyProperty property, object oldValue)
        { 
            _uiElement = uiElement;
            _property = property;
            _oldValue = oldValue;
        } 

        #endregion Constructors 
 
        //------------------------------------------------------
        // 
        //  Public Methods
        //
        //-----------------------------------------------------
 
        #region Public Methods
 
        // Called by the undo manager.  Restores tree state to its condition 
        // when the unit was created.
        public void Do() 
        {
            if (_oldValue != DependencyProperty.UnsetValue)
            {
                _uiElement.SetValue(_property, _oldValue); 
            }
            else 
            { 
                _uiElement.ClearValue(_property);
            } 
        }

        // Called by the undo manager.
        public bool Merge(IUndoUnit unit) 
        {
            Invariant.Assert(unit != null); 
            return false; 
        }
 
        #endregion Public Methods

        //------------------------------------------------------
        // 
        //  Internal Methods
        // 
        //------------------------------------------------------ 

        #region Internal Methods 

        // Note that following strongly typed overloads of Add are meant to restrict the usage of UIElementPropertyUndoUnit
        // for tracking changes to only a limited set of properties of UIElements.
        // In general, it is not safe to keep a reference to the original property value, however for enum types, it is safe to do so. 

        // Add a new UIElementPropertyUndoUnit to the undo stack for HorizontalAlignment property. 
        internal static void Add(ITextContainer textContainer, UIElement uiElement, DependencyProperty property, HorizontalAlignment newValue) 
        {
            AddPrivate(textContainer, uiElement, property, newValue); 
        }

        // Add a new UIElementPropertyUndoUnit to the undo stack for FlowDirection property.
        internal static void Add(ITextContainer textContainer, UIElement uiElement, DependencyProperty property, FlowDirection newValue) 
        {
            AddPrivate(textContainer, uiElement, property, newValue); 
        } 

        #endregion Internal Methods 

        //-----------------------------------------------------
        //
        //  Privte Methods 
        //
        //------------------------------------------------------ 
 
        #region Private Methods
 
        // Private helper that adds a new UIElementPropertyUndoUnit to the undo stack.
        private static void AddPrivate(ITextContainer textContainer, UIElement uiElement, DependencyProperty property, object newValue)
        {
            UndoManager undoManager = TextTreeUndo.GetOrClearUndoManager(textContainer); 

            if (undoManager == null) 
            { 
                return;
            } 

            object currentValue = uiElement.ReadLocalValue(property);

            if (currentValue is Expression) 
            {
                // Can't undo when old value is an expression, so clear the stack. 
                if (undoManager.IsEnabled) 
                {
                    undoManager.Clear(); 
                }
                return;
            }
 
            if (currentValue.Equals(newValue))
            { 
                // No property change. 
                return;
            } 

            undoManager.Add(new UIElementPropertyUndoUnit(uiElement, property, currentValue));
        }
 
        #endregion Private Methods
 
        //----------------------------------------------------- 
        //
        //  Private Fields 
        //
        //-----------------------------------------------------

        #region Private Fields 

        // UIElement associated with this undo unit. 
        private readonly UIElement _uiElement; 

        // DependencyProperty of the UIElement associated with this undo unit. 
        private readonly DependencyProperty _property;

        // Original property value.
        private readonly object _oldValue; 

        #endregion Private Fields 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK