EraserBehavior.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 / MS / Internal / Ink / EraserBehavior.cs / 1305600 / EraserBehavior.cs

                            //---------------------------------------------------------------------------- 
//
// File: EraserBehavior.cs
//
// Description: 
// ErasingBehavior for Ink
// Features: 
// 
// History:
//  3/15/2003 samgeo:       Created 
//
// Copyright (C) 2003 by Microsoft Corporation.  All rights reserved.
//
//--------------------------------------------------------------------------- 
using System;
using System.ComponentModel; 
using System.ComponentModel.Design; 
using System.Collections;
using System.Collections.Generic; 
using System.Diagnostics;
using System.Windows.Input;
using System.Windows;
using System.Windows.Controls; 
using System.Windows.Controls.Primitives;
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Ink;
using System.Windows.Interop; 
using System.Windows.Navigation;
using System.Windows.Media;
using Swi = System.Windows.Ink;
 
namespace MS.Internal.Ink
{ 
    ///  
    /// Eraser Behavior
    ///  
    internal sealed class EraserBehavior : StylusEditingBehavior
    {
        //-------------------------------------------------------------------------------
        // 
        // Constructors
        // 
        //------------------------------------------------------------------------------- 

        #region Constructors 

        internal EraserBehavior(EditingCoordinator editingCoordinator, InkCanvas inkCanvas)
            : base(editingCoordinator, inkCanvas)
        { 
        }
 
        #endregion Constructors 

        //-------------------------------------------------------------------------------- 
        //
        // Protected Methods
        //
        //------------------------------------------------------------------------------- 

        #region Protected Methods 
 
        /// 
        /// Overrides SwitchToMode as the following expectations 
        /// 19. From EraseByPoint To InkAndGesture
        ///     After mode change ink is being collected. On StylusUp gesture event fires. If it’s not a gesture, StrokeCollected event fires.
        /// 20. From EraseByPoint To GestureOnly
        ///     After mode change ink is being collected. On StylusUp gesture event fires. Stroke gets removed on StylusUp even if it’s not a gesture. 
        /// 21. From EraseByPoint To Ink
        ///     Ink collection starts when changing the mode. 
        /// 22. From EraseByPoint To EraseByStroke 
        ///     After mode change StrokeErasing is performed.
        /// 23. From EraseByPoint To Select 
        ///     Lasso is drawn for all packets between StylusDown and StylusUp. Strokes/elements within the lasso will be selected.
        /// 24. From EraseByPoint To None
        ///     No erasing is performed after mode change.
        /// 25. From EraseByStroke To InkAndGesture 
        ///     After mode change ink is being collected. On StylusUp gesture event fires. If it’s not a gesture, StrokeCollected event fires.
        /// 26. From EraseByStroke To GestureOnly 
        ///     After mode change ink is being collected. On StylusUp gesture event fires. Stroke gets removed on StylusUp even if it’s not a gesture. 
        /// 27. From EraseByStroke To EraseByPoint
        ///     After mode change PointErasing is performed. 
        /// 28. From EraseByStroke To Ink
        ///     Ink collection starts when changing the mode.
        /// 29. From EraseByStroke To Select
        ///     Lasso is drawn for all packets between StylusDown and StylusUp. Strokes/elements within the lasso will be selected 
        /// 30. From EraseByStroke To None
        ///     No erasing is performed after mode change. 
        ///  
        /// 
        protected override void OnSwitchToMode(InkCanvasEditingMode mode) 
        {
            Debug.Assert(EditingCoordinator.IsInMidStroke, "SwitchToMode should only be called in a mid-stroke");

            switch ( mode ) 
            {
                case InkCanvasEditingMode.Ink: 
                case InkCanvasEditingMode.InkAndGesture: 
                case InkCanvasEditingMode.GestureOnly:
                    { 
                        // Commit the current behavior
                        Commit(true);

                        // Change the mode. The dynamic renderer will be reset automatically. 
                        EditingCoordinator.ChangeStylusEditingMode(this, mode);
                        break; 
                    } 
                case InkCanvasEditingMode.EraseByPoint:
                case InkCanvasEditingMode.EraseByStroke: 
                    {
                        Debug.Assert(_cachedEraseMode != mode);

                        // Commit the current behavior 
                        Commit(true);
 
                        // Change the mode 
                        EditingCoordinator.ChangeStylusEditingMode(this, mode);
 
                        break;
                    }
                case InkCanvasEditingMode.Select:
                    { 
                        // Make a copy of the current cached points.
                        StylusPointCollection cachedPoints = _stylusPoints != null ? 
                                                                _stylusPoints.Clone() : null; 

                        // Commit the current behavior. 
                        Commit(true);

                        // Change the Select mode
                        IStylusEditing newBehavior = EditingCoordinator.ChangeStylusEditingMode(this, mode); 

                        if ( cachedPoints != null 
                            // NOTICE-2006/04/27-WAYNEZEN, 
                            // EditingCoordinator.ChangeStylusEditingMode raises external event.
                            // The user code could take any arbitrary action for instance calling InkCanvas.ReleaseMouseCapture() 
                            // So there is no guarantee that we could receive the newBehavior.
                            && newBehavior != null )
                        {
                            // Now add the previous points to the lasso behavior 
                            newBehavior.AddStylusPoints(cachedPoints, false/*userInitiated*/);
                        } 
 
                        break;
                    } 
                case InkCanvasEditingMode.None:
                    {
                        // Discard the collected ink.
                        Commit(true); 

                        // Change to the None mode 
                        EditingCoordinator.ChangeStylusEditingMode(this, mode); 
                        break;
                    } 
                default:
                    Debug.Assert(false, "Unknown InkCanvasEditingMode!");
                    break;
            } 
        }
 
        protected override void OnActivate() 
        {
            base.OnActivate(); 
            InkCanvasEditingMode newEraseMode = EditingCoordinator.ActiveEditingMode;
            Debug.Assert(newEraseMode == InkCanvasEditingMode.EraseByPoint
                            || newEraseMode == InkCanvasEditingMode.EraseByStroke);
 
            // Check whether we have to update cursor.
            if ( _cachedEraseMode != newEraseMode ) 
            { 
                // EraseMode is changed
                _cachedEraseMode = newEraseMode; 
                EditingCoordinator.InvalidateBehaviorCursor(this);
            }
            else if ( newEraseMode == InkCanvasEditingMode.EraseByPoint )
            { 
                // Invalidate the PointEraser if we don't have the cache yet.
                bool isPointEraserCursorValid = _cachedStylusShape != null; 
 
                // NTRAID:WINDOWSOS#1673398-2006/05/23-WAYNEZEN,
                // If the cached EraserShape is different from the current EraserShape, we shoud just reset the cache. 
                // The new cursor will be generated when it's needed later.
                if ( isPointEraserCursorValid
                    && ( _cachedStylusShape.Width != InkCanvas.EraserShape.Width
                        || _cachedStylusShape.Height != InkCanvas.EraserShape.Height 
                        || _cachedStylusShape.Rotation != InkCanvas.EraserShape.Rotation
                        || _cachedStylusShape.GetType() != InkCanvas.EraserShape.GetType()) ) 
                { 
                    Debug.Assert(_cachedPointEraserCursor != null, "_cachedPointEraserCursor shouldn't be null.");
                    ResetCachedPointEraserCursor(); 
                    isPointEraserCursorValid = false;
                }

                if ( !isPointEraserCursorValid ) 
                {
                    // EraserShape is changed when the new mode is EraseByPoint 
                    EditingCoordinator.InvalidateBehaviorCursor(this); 
                }
            } 
        }

        /// 
        /// StylusInputBegin 
        /// 
        /// stylusPoints 
        /// true if the source eventArgs.UserInitiated flag was set to true 
        protected override void StylusInputBegin(StylusPointCollection stylusPoints, bool userInitiated)
        { 
            //
            // get a disposable dynamic hit-tester and add event handler
            //
            _incrementalStrokeHitTester = 
                                this.InkCanvas.Strokes.GetIncrementalStrokeHitTester(this.InkCanvas.EraserShape);
 
 
            if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode )
            { 
                _incrementalStrokeHitTester.StrokeHit += new StrokeHitEventHandler(OnPointEraseResultChanged);
            }
            else
            { 
                //we're in stroke hit test mode
                _incrementalStrokeHitTester.StrokeHit += new StrokeHitEventHandler(OnStrokeEraseResultChanged); 
            } 

            _stylusPoints = new StylusPointCollection(stylusPoints.Description, 100); 
            _stylusPoints.Add(stylusPoints);

            //
            // start erasing 
            //
            _incrementalStrokeHitTester.AddPoints(stylusPoints); 
 
            // NTRAID:WINDOWSOS#1642274-2006/05/10-WAYNEZEN,
            // Since InkCanvas will ignore the animated tranforms when it receives the property changes. 
            // So we should update our cursor when the stylus is down if there are animated transforms applied to InkCanvas.
            if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode )
            {
                // Call InvalidateBehaviorCursor at the end of the routine. The method will cause an external event fired. 
                // So it should be invoked after we set up our states.
                EditingCoordinator.InvalidateBehaviorCursor(this); 
            } 
        }
 
        /// 
        /// StylusInputContinue
        /// 
        /// stylusPoints 
        /// true if the source eventArgs.UserInitiated flag was set to true
        protected override void StylusInputContinue(StylusPointCollection stylusPoints, bool userInitiated) 
        { 
            _stylusPoints.Add(stylusPoints);
 
            _incrementalStrokeHitTester.AddPoints(stylusPoints);
        }

        ///  
        /// StylusInputEnd
        ///  
        /// commit 
        protected override void StylusInputEnd(bool commit)
        { 
            if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode )
            {
                _incrementalStrokeHitTester.StrokeHit-= new StrokeHitEventHandler(OnPointEraseResultChanged);
            } 
            else
            { 
                //we're in stroke hit test mode 
                _incrementalStrokeHitTester.StrokeHit -= new StrokeHitEventHandler(OnStrokeEraseResultChanged);
            } 

            _stylusPoints = null;

            // NTRAID#T2-26868-2004/11/1-WAYNEZEN, 
            // Don't forget ending the current incremental hit testing.
            _incrementalStrokeHitTester.EndHitTesting(); 
            _incrementalStrokeHitTester = null; 
        }
 
        /// 
        /// Get eraser cursor.
        /// 
        ///  
        protected override Cursor GetCurrentCursor()
        { 
            if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode ) 
            {
                if ( _cachedPointEraserCursor == null ) 
                {
                    _cachedStylusShape = InkCanvas.EraserShape;

                    // NTRAID-WINDOWS#1430638-2006/01/04-WAYNEZEN, 
                    // The eraser cursor should respect the InkCanvas' Transform properties as the pen tip.
                    Matrix xf = GetElementTransformMatrix(); 
                    if ( !xf.IsIdentity ) 
                    {
                        // Zero the offsets if the element's transform in invertable. 
                        // Otherwise fallback the matrix to the identity.
                        if ( xf.HasInverse )
                        {
                            xf.OffsetX = 0; 
                            xf.OffsetY = 0;
                        } 
                        else 
                        {
                            xf = Matrix.Identity; 
                        }
                    }
                    _cachedPointEraserCursor = PenCursorManager.GetPointEraserCursor(_cachedStylusShape, xf);
                } 

                return _cachedPointEraserCursor; 
            } 
            else
            { 
                return PenCursorManager.GetStrokeEraserCursor();
            }
        }
 
        /// 
        /// ApplyTransformToCursor 
        ///  
        protected override void OnTransformChanged()
        { 
            // Reset the cached point eraser cursor.
            ResetCachedPointEraserCursor();
        }
 
        #endregion Protected Methods
 
        //-------------------------------------------------------------------------------- 
        //
        // Private Methods 
        //
        //--------------------------------------------------------------------------------

        #region Private Methods 

        ///  
        /// Reset the cached point eraser cursor. 
        /// 
        private void ResetCachedPointEraserCursor() 
        {
            _cachedPointEraserCursor = null;
            _cachedStylusShape = null;
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        private void OnStrokeEraseResultChanged(object sender, StrokeHitEventArgs e)
        {
            Debug.Assert(null != e.HitStroke); 

            bool fSucceeded = false; 
 
            // The below code calls out StrokeErasing or StrokeErased event.
            // The out-side code could throw exception. 
            // We use try/finally block to protect our status.
            try
            {
                InkCanvasStrokeErasingEventArgs args = new InkCanvasStrokeErasingEventArgs(e.HitStroke); 
                this.InkCanvas.RaiseStrokeErasing(args);
 
                if ( !args.Cancel ) 
                {
                    // Erase only if the event wasn't cancelled 
                    InkCanvas.Strokes.Remove(e.HitStroke);
                    this.InkCanvas.RaiseInkErased();
                }
 
                fSucceeded = true;
            } 
            finally 
            {
                if ( !fSucceeded ) 
                {
                    // Abort the editing.
                    Commit(false);
                } 
            }
        } 
 
        /// 
        /// 
        /// 
        /// 
        /// 
        private void OnPointEraseResultChanged(object sender, StrokeHitEventArgs e) 
        {
            Debug.Assert(null != e.HitStroke, "e.HitStroke cannot be null"); 
 
            bool fSucceeded = false;
 
            // The below code might call out StrokeErasing or StrokeErased event.
            // The out-side code could throw exception.
            // We use try/finally block to protect our status.
            try 
            {
 
                InkCanvasStrokeErasingEventArgs args = new InkCanvasStrokeErasingEventArgs(e.HitStroke); 
                this.InkCanvas.RaiseStrokeErasing(args);
 
                if ( !args.Cancel )
                {
                    // Erase only if the event wasn't cancelled
                    StrokeCollection eraseResult = e.GetPointEraseResults(); 
                    Debug.Assert(eraseResult != null, "eraseResult cannot be null");
 
                    StrokeCollection strokesToReplace = new StrokeCollection(); 
                    strokesToReplace.Add(e.HitStroke);
 
                    try
                    {
                        // replace or remove the stroke
                        if (eraseResult.Count > 0) 
                        {
                            this.InkCanvas.Strokes.Replace(strokesToReplace, eraseResult); 
                        } 
                        else
                        { 
                            this.InkCanvas.Strokes.Remove(strokesToReplace);
                        }
                    }
                    catch (ArgumentException ex) 
                    {
                        //this can happen if someone sits in an event handler 
                        //for StrokeErasing and removes the stroke. 
                        //this to harden against failure here.
                        if (!ex.Data.Contains("System.Windows.Ink.StrokeCollection")) 
                        {
                            //System.Windows.Ink.StrokeCollection didn't throw this,
                            //we need to just throw the original exception
                            throw; 
                        }
                    } 
 

                    //raise ink erased 
                    this.InkCanvas.RaiseInkErased();
                }

                fSucceeded = true; 
            }
            finally 
            { 
                if ( !fSucceeded )
                { 
                    // Abort the editing.
                    Commit(false);
                }
            } 
        }
 
        #endregion Private Methods 

        //------------------------------------------------------------------------------- 
        //
        // Private Fields
        //
        //-------------------------------------------------------------------------------- 

        #region Private Fields 
 
        private InkCanvasEditingMode            _cachedEraseMode;
        private IncrementalStrokeHitTester      _incrementalStrokeHitTester; 
        private Cursor                          _cachedPointEraserCursor;
        private StylusShape                     _cachedStylusShape;
        private StylusPointCollection           _stylusPoints = null;
 
        #endregion Private Fields
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// File: EraserBehavior.cs
//
// Description: 
// ErasingBehavior for Ink
// Features: 
// 
// History:
//  3/15/2003 samgeo:       Created 
//
// Copyright (C) 2003 by Microsoft Corporation.  All rights reserved.
//
//--------------------------------------------------------------------------- 
using System;
using System.ComponentModel; 
using System.ComponentModel.Design; 
using System.Collections;
using System.Collections.Generic; 
using System.Diagnostics;
using System.Windows.Input;
using System.Windows;
using System.Windows.Controls; 
using System.Windows.Controls.Primitives;
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Ink;
using System.Windows.Interop; 
using System.Windows.Navigation;
using System.Windows.Media;
using Swi = System.Windows.Ink;
 
namespace MS.Internal.Ink
{ 
    ///  
    /// Eraser Behavior
    ///  
    internal sealed class EraserBehavior : StylusEditingBehavior
    {
        //-------------------------------------------------------------------------------
        // 
        // Constructors
        // 
        //------------------------------------------------------------------------------- 

        #region Constructors 

        internal EraserBehavior(EditingCoordinator editingCoordinator, InkCanvas inkCanvas)
            : base(editingCoordinator, inkCanvas)
        { 
        }
 
        #endregion Constructors 

        //-------------------------------------------------------------------------------- 
        //
        // Protected Methods
        //
        //------------------------------------------------------------------------------- 

        #region Protected Methods 
 
        /// 
        /// Overrides SwitchToMode as the following expectations 
        /// 19. From EraseByPoint To InkAndGesture
        ///     After mode change ink is being collected. On StylusUp gesture event fires. If it’s not a gesture, StrokeCollected event fires.
        /// 20. From EraseByPoint To GestureOnly
        ///     After mode change ink is being collected. On StylusUp gesture event fires. Stroke gets removed on StylusUp even if it’s not a gesture. 
        /// 21. From EraseByPoint To Ink
        ///     Ink collection starts when changing the mode. 
        /// 22. From EraseByPoint To EraseByStroke 
        ///     After mode change StrokeErasing is performed.
        /// 23. From EraseByPoint To Select 
        ///     Lasso is drawn for all packets between StylusDown and StylusUp. Strokes/elements within the lasso will be selected.
        /// 24. From EraseByPoint To None
        ///     No erasing is performed after mode change.
        /// 25. From EraseByStroke To InkAndGesture 
        ///     After mode change ink is being collected. On StylusUp gesture event fires. If it’s not a gesture, StrokeCollected event fires.
        /// 26. From EraseByStroke To GestureOnly 
        ///     After mode change ink is being collected. On StylusUp gesture event fires. Stroke gets removed on StylusUp even if it’s not a gesture. 
        /// 27. From EraseByStroke To EraseByPoint
        ///     After mode change PointErasing is performed. 
        /// 28. From EraseByStroke To Ink
        ///     Ink collection starts when changing the mode.
        /// 29. From EraseByStroke To Select
        ///     Lasso is drawn for all packets between StylusDown and StylusUp. Strokes/elements within the lasso will be selected 
        /// 30. From EraseByStroke To None
        ///     No erasing is performed after mode change. 
        ///  
        /// 
        protected override void OnSwitchToMode(InkCanvasEditingMode mode) 
        {
            Debug.Assert(EditingCoordinator.IsInMidStroke, "SwitchToMode should only be called in a mid-stroke");

            switch ( mode ) 
            {
                case InkCanvasEditingMode.Ink: 
                case InkCanvasEditingMode.InkAndGesture: 
                case InkCanvasEditingMode.GestureOnly:
                    { 
                        // Commit the current behavior
                        Commit(true);

                        // Change the mode. The dynamic renderer will be reset automatically. 
                        EditingCoordinator.ChangeStylusEditingMode(this, mode);
                        break; 
                    } 
                case InkCanvasEditingMode.EraseByPoint:
                case InkCanvasEditingMode.EraseByStroke: 
                    {
                        Debug.Assert(_cachedEraseMode != mode);

                        // Commit the current behavior 
                        Commit(true);
 
                        // Change the mode 
                        EditingCoordinator.ChangeStylusEditingMode(this, mode);
 
                        break;
                    }
                case InkCanvasEditingMode.Select:
                    { 
                        // Make a copy of the current cached points.
                        StylusPointCollection cachedPoints = _stylusPoints != null ? 
                                                                _stylusPoints.Clone() : null; 

                        // Commit the current behavior. 
                        Commit(true);

                        // Change the Select mode
                        IStylusEditing newBehavior = EditingCoordinator.ChangeStylusEditingMode(this, mode); 

                        if ( cachedPoints != null 
                            // NOTICE-2006/04/27-WAYNEZEN, 
                            // EditingCoordinator.ChangeStylusEditingMode raises external event.
                            // The user code could take any arbitrary action for instance calling InkCanvas.ReleaseMouseCapture() 
                            // So there is no guarantee that we could receive the newBehavior.
                            && newBehavior != null )
                        {
                            // Now add the previous points to the lasso behavior 
                            newBehavior.AddStylusPoints(cachedPoints, false/*userInitiated*/);
                        } 
 
                        break;
                    } 
                case InkCanvasEditingMode.None:
                    {
                        // Discard the collected ink.
                        Commit(true); 

                        // Change to the None mode 
                        EditingCoordinator.ChangeStylusEditingMode(this, mode); 
                        break;
                    } 
                default:
                    Debug.Assert(false, "Unknown InkCanvasEditingMode!");
                    break;
            } 
        }
 
        protected override void OnActivate() 
        {
            base.OnActivate(); 
            InkCanvasEditingMode newEraseMode = EditingCoordinator.ActiveEditingMode;
            Debug.Assert(newEraseMode == InkCanvasEditingMode.EraseByPoint
                            || newEraseMode == InkCanvasEditingMode.EraseByStroke);
 
            // Check whether we have to update cursor.
            if ( _cachedEraseMode != newEraseMode ) 
            { 
                // EraseMode is changed
                _cachedEraseMode = newEraseMode; 
                EditingCoordinator.InvalidateBehaviorCursor(this);
            }
            else if ( newEraseMode == InkCanvasEditingMode.EraseByPoint )
            { 
                // Invalidate the PointEraser if we don't have the cache yet.
                bool isPointEraserCursorValid = _cachedStylusShape != null; 
 
                // NTRAID:WINDOWSOS#1673398-2006/05/23-WAYNEZEN,
                // If the cached EraserShape is different from the current EraserShape, we shoud just reset the cache. 
                // The new cursor will be generated when it's needed later.
                if ( isPointEraserCursorValid
                    && ( _cachedStylusShape.Width != InkCanvas.EraserShape.Width
                        || _cachedStylusShape.Height != InkCanvas.EraserShape.Height 
                        || _cachedStylusShape.Rotation != InkCanvas.EraserShape.Rotation
                        || _cachedStylusShape.GetType() != InkCanvas.EraserShape.GetType()) ) 
                { 
                    Debug.Assert(_cachedPointEraserCursor != null, "_cachedPointEraserCursor shouldn't be null.");
                    ResetCachedPointEraserCursor(); 
                    isPointEraserCursorValid = false;
                }

                if ( !isPointEraserCursorValid ) 
                {
                    // EraserShape is changed when the new mode is EraseByPoint 
                    EditingCoordinator.InvalidateBehaviorCursor(this); 
                }
            } 
        }

        /// 
        /// StylusInputBegin 
        /// 
        /// stylusPoints 
        /// true if the source eventArgs.UserInitiated flag was set to true 
        protected override void StylusInputBegin(StylusPointCollection stylusPoints, bool userInitiated)
        { 
            //
            // get a disposable dynamic hit-tester and add event handler
            //
            _incrementalStrokeHitTester = 
                                this.InkCanvas.Strokes.GetIncrementalStrokeHitTester(this.InkCanvas.EraserShape);
 
 
            if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode )
            { 
                _incrementalStrokeHitTester.StrokeHit += new StrokeHitEventHandler(OnPointEraseResultChanged);
            }
            else
            { 
                //we're in stroke hit test mode
                _incrementalStrokeHitTester.StrokeHit += new StrokeHitEventHandler(OnStrokeEraseResultChanged); 
            } 

            _stylusPoints = new StylusPointCollection(stylusPoints.Description, 100); 
            _stylusPoints.Add(stylusPoints);

            //
            // start erasing 
            //
            _incrementalStrokeHitTester.AddPoints(stylusPoints); 
 
            // NTRAID:WINDOWSOS#1642274-2006/05/10-WAYNEZEN,
            // Since InkCanvas will ignore the animated tranforms when it receives the property changes. 
            // So we should update our cursor when the stylus is down if there are animated transforms applied to InkCanvas.
            if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode )
            {
                // Call InvalidateBehaviorCursor at the end of the routine. The method will cause an external event fired. 
                // So it should be invoked after we set up our states.
                EditingCoordinator.InvalidateBehaviorCursor(this); 
            } 
        }
 
        /// 
        /// StylusInputContinue
        /// 
        /// stylusPoints 
        /// true if the source eventArgs.UserInitiated flag was set to true
        protected override void StylusInputContinue(StylusPointCollection stylusPoints, bool userInitiated) 
        { 
            _stylusPoints.Add(stylusPoints);
 
            _incrementalStrokeHitTester.AddPoints(stylusPoints);
        }

        ///  
        /// StylusInputEnd
        ///  
        /// commit 
        protected override void StylusInputEnd(bool commit)
        { 
            if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode )
            {
                _incrementalStrokeHitTester.StrokeHit-= new StrokeHitEventHandler(OnPointEraseResultChanged);
            } 
            else
            { 
                //we're in stroke hit test mode 
                _incrementalStrokeHitTester.StrokeHit -= new StrokeHitEventHandler(OnStrokeEraseResultChanged);
            } 

            _stylusPoints = null;

            // NTRAID#T2-26868-2004/11/1-WAYNEZEN, 
            // Don't forget ending the current incremental hit testing.
            _incrementalStrokeHitTester.EndHitTesting(); 
            _incrementalStrokeHitTester = null; 
        }
 
        /// 
        /// Get eraser cursor.
        /// 
        ///  
        protected override Cursor GetCurrentCursor()
        { 
            if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode ) 
            {
                if ( _cachedPointEraserCursor == null ) 
                {
                    _cachedStylusShape = InkCanvas.EraserShape;

                    // NTRAID-WINDOWS#1430638-2006/01/04-WAYNEZEN, 
                    // The eraser cursor should respect the InkCanvas' Transform properties as the pen tip.
                    Matrix xf = GetElementTransformMatrix(); 
                    if ( !xf.IsIdentity ) 
                    {
                        // Zero the offsets if the element's transform in invertable. 
                        // Otherwise fallback the matrix to the identity.
                        if ( xf.HasInverse )
                        {
                            xf.OffsetX = 0; 
                            xf.OffsetY = 0;
                        } 
                        else 
                        {
                            xf = Matrix.Identity; 
                        }
                    }
                    _cachedPointEraserCursor = PenCursorManager.GetPointEraserCursor(_cachedStylusShape, xf);
                } 

                return _cachedPointEraserCursor; 
            } 
            else
            { 
                return PenCursorManager.GetStrokeEraserCursor();
            }
        }
 
        /// 
        /// ApplyTransformToCursor 
        ///  
        protected override void OnTransformChanged()
        { 
            // Reset the cached point eraser cursor.
            ResetCachedPointEraserCursor();
        }
 
        #endregion Protected Methods
 
        //-------------------------------------------------------------------------------- 
        //
        // Private Methods 
        //
        //--------------------------------------------------------------------------------

        #region Private Methods 

        ///  
        /// Reset the cached point eraser cursor. 
        /// 
        private void ResetCachedPointEraserCursor() 
        {
            _cachedPointEraserCursor = null;
            _cachedStylusShape = null;
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        private void OnStrokeEraseResultChanged(object sender, StrokeHitEventArgs e)
        {
            Debug.Assert(null != e.HitStroke); 

            bool fSucceeded = false; 
 
            // The below code calls out StrokeErasing or StrokeErased event.
            // The out-side code could throw exception. 
            // We use try/finally block to protect our status.
            try
            {
                InkCanvasStrokeErasingEventArgs args = new InkCanvasStrokeErasingEventArgs(e.HitStroke); 
                this.InkCanvas.RaiseStrokeErasing(args);
 
                if ( !args.Cancel ) 
                {
                    // Erase only if the event wasn't cancelled 
                    InkCanvas.Strokes.Remove(e.HitStroke);
                    this.InkCanvas.RaiseInkErased();
                }
 
                fSucceeded = true;
            } 
            finally 
            {
                if ( !fSucceeded ) 
                {
                    // Abort the editing.
                    Commit(false);
                } 
            }
        } 
 
        /// 
        /// 
        /// 
        /// 
        /// 
        private void OnPointEraseResultChanged(object sender, StrokeHitEventArgs e) 
        {
            Debug.Assert(null != e.HitStroke, "e.HitStroke cannot be null"); 
 
            bool fSucceeded = false;
 
            // The below code might call out StrokeErasing or StrokeErased event.
            // The out-side code could throw exception.
            // We use try/finally block to protect our status.
            try 
            {
 
                InkCanvasStrokeErasingEventArgs args = new InkCanvasStrokeErasingEventArgs(e.HitStroke); 
                this.InkCanvas.RaiseStrokeErasing(args);
 
                if ( !args.Cancel )
                {
                    // Erase only if the event wasn't cancelled
                    StrokeCollection eraseResult = e.GetPointEraseResults(); 
                    Debug.Assert(eraseResult != null, "eraseResult cannot be null");
 
                    StrokeCollection strokesToReplace = new StrokeCollection(); 
                    strokesToReplace.Add(e.HitStroke);
 
                    try
                    {
                        // replace or remove the stroke
                        if (eraseResult.Count > 0) 
                        {
                            this.InkCanvas.Strokes.Replace(strokesToReplace, eraseResult); 
                        } 
                        else
                        { 
                            this.InkCanvas.Strokes.Remove(strokesToReplace);
                        }
                    }
                    catch (ArgumentException ex) 
                    {
                        //this can happen if someone sits in an event handler 
                        //for StrokeErasing and removes the stroke. 
                        //this to harden against failure here.
                        if (!ex.Data.Contains("System.Windows.Ink.StrokeCollection")) 
                        {
                            //System.Windows.Ink.StrokeCollection didn't throw this,
                            //we need to just throw the original exception
                            throw; 
                        }
                    } 
 

                    //raise ink erased 
                    this.InkCanvas.RaiseInkErased();
                }

                fSucceeded = true; 
            }
            finally 
            { 
                if ( !fSucceeded )
                { 
                    // Abort the editing.
                    Commit(false);
                }
            } 
        }
 
        #endregion Private Methods 

        //------------------------------------------------------------------------------- 
        //
        // Private Fields
        //
        //-------------------------------------------------------------------------------- 

        #region Private Fields 
 
        private InkCanvasEditingMode            _cachedEraseMode;
        private IncrementalStrokeHitTester      _incrementalStrokeHitTester; 
        private Cursor                          _cachedPointEraserCursor;
        private StylusShape                     _cachedStylusShape;
        private StylusPointCollection           _stylusPoints = null;
 
        #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