/// <summary> /// The implementation behind the public methods AddPoint/AddPoints /// </summary> /// <param name="points">a set of points representing the last increment /// in the moving of the erasing shape</param> protected override void AddPointsCore(IEnumerable <Point> points) { System.Diagnostics.Debug.Assert((points != null) && (IEnumerablePointHelper.GetCount(points) != 0)); System.Diagnostics.Debug.Assert(_erasingStroke != null); // Move the shape through the new points and build the contour of the move. _erasingStroke.MoveTo(points); Rect erasingBounds = _erasingStroke.Bounds; if (erasingBounds.IsEmpty) { return; } List <StrokeHitEventArgs> strokeHitEventArgCollection = null; // Do nothing if there's nobody listening to the events if (StrokeHit != null) { List <StrokeIntersection> eraseAt = new List <StrokeIntersection>(); // Test stroke by stroke and collect the results. for (int x = 0; x < this.StrokeInfos.Count; x++) { StrokeInfo strokeInfo = this.StrokeInfos[x]; // Skip the stroke if its bounding box doesn't intersect with the one of the hitting shape. if ((erasingBounds.IntersectsWith(strokeInfo.StrokeBounds) == false) || (_erasingStroke.EraseTest(StrokeNodeIterator.GetIterator(strokeInfo.Stroke, strokeInfo.Stroke.DrawingAttributes), eraseAt) == false)) { continue; } // Create an event args to raise after done with hit-testing // We don't fire these events right away because user is expected to // modify the stroke collection in her event handler, and that would // invalidate this foreach loop. if (strokeHitEventArgCollection == null) { strokeHitEventArgCollection = new List <StrokeHitEventArgs>(); } strokeHitEventArgCollection.Add(new StrokeHitEventArgs(strokeInfo.Stroke, eraseAt.ToArray())); // We must clear eraseAt or it will contain invalid results for the next strokes eraseAt.Clear(); } } // Raise StrokeHit event if needed. if (strokeHitEventArgCollection != null) { System.Diagnostics.Debug.Assert(strokeHitEventArgCollection.Count != 0); for (int x = 0; x < strokeHitEventArgCollection.Count; x++) { StrokeHitEventArgs eventArgs = strokeHitEventArgCollection[x]; System.Diagnostics.Debug.Assert(eventArgs.HitStroke != null); OnStrokeHit(eventArgs); } } }
/// <summary> /// Event raiser for StrokeHit /// </summary> protected void OnStrokeHit(StrokeHitEventArgs eventArgs) { System.Diagnostics.Debug.Assert(eventArgs != null); if (StrokeHit != null) { StrokeHit(this, eventArgs); } }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> 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); } } }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> 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); } } }
protected void OnStrokeHit(StrokeHitEventArgs eventArgs) { }