添加一个支持多点触摸的画布
/// <summary>
/// 支持多点触摸的InkCanvas
/// </summary
public class MultiTouchCanvas : FrameworkElement
{
private InkCanvasProxy _inkCanvas = new InkCanvasProxy();
private Grid transparentOverlay = new Grid();
private StrokeType _strokeType = StrokeType.Stroke;
private Dictionary<object, StrokeCollection> _strokes = new Dictionary<object, StrokeCollection>();
private Dictionary<object, Stroke> _currentStroke = new Dictionary<object, Stroke>();
private Color _penColor = Colors.Green;
public Color PenColor{
get{
return this._inkCanvas.DefaultDrawingAttributes.Color;
}
set{
this._penColor = value;
this._inkCanvas.DefaultDrawingAttributes.Color = value;
if (this.PenType == StrokeType.HighlighterStroke)
{
value.ScA = System.Convert.ToSingle(0.5);
this._inkCanvas.DefaultDrawingAttributes.Color = value;
}
}
}
private double _penWidth = 4.0;
public double PenWidth
{
get { return this._penWidth; }
set
{
this._penWidth = value;
this._inkCanvas.DefaultDrawingAttributes.Width = value;
this._inkCanvas.DefaultDrawingAttributes.Height = value;
}
}
private double _eraseWidth = 30.0;
public double EraseWidth
{
get
{
return this._eraseWidth;
}
set
{
this._eraseWidth = value;
this._inkCanvas.DefaultDrawingAttributes.Height = value;
this._inkCanvas.DefaultDrawingAttributes.Width = value;
}
}
public StrokeType PenType
{
get { return this._strokeType; }
set
{
this._strokeType = value;
if (this._strokeType == StrokeType.Stroke || this._strokeType == StrokeType.HighlighterStroke)
{
this._inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
this._inkCanvas.DefaultDrawingAttributes.Width = this.PenWidth;
this._inkCanvas.DefaultDrawingAttributes.Height = this.PenWidth;
this._inkCanvas.DefaultDrawingAttributes.Color = this.PenColor;
}
if (this._strokeType == StrokeType.HighlighterStroke)
{
Color dColor = this.PenColor;
dColor.ScA = System.Convert.ToSingle(0.5);
this._inkCanvas.DefaultDrawingAttributes.Color = dColor;
}
if (this._strokeType == StrokeType.EraseByPoint)
{
this._inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
this._inkCanvas.DefaultDrawingAttributes.Width = this.EraseWidth;
this._inkCanvas.DefaultDrawingAttributes.Height = this.EraseWidth;
}
}
}
public Brush Background
{
get { return this._inkCanvas.Background; }
set
{
this._inkCanvas.Background = value;
}
}
protected override int VisualChildrenCount
{
get
{
return 2; //grid + inkcanvas
}
}
public MultiTouchCanvas(){
base.IsManipulationEnabled = true;
this.transparentOverlay.Background = Brushes.Transparent;
base.IsEnabled =true;
this.InitInkCanvasPropertys();
this._inkCanvas.DefaultDrawingAttributes = new DrawingAttributes();
this._inkCanvas.DefaultDrawingAttributes.Color = Colors.Green;
this._inkCanvas.DefaultDrawingAttributes.Width = 4;
this._inkCanvas.DefaultDrawingAttributes.Height = 4;
this.PenType = StrokeType.Stroke;
}
public void ClearStrokes(object device)
{
if (this._strokes.ContainsKey(device) && this._inkCanvas.Strokes != null && this._inkCanvas.Strokes.Count > 0)
{
StrokeCollection sc = this._strokes[device];
this._inkCanvas.Strokes.Remove(sc);
this._strokes.Remove(device);
}
}
public StrokeCollection GetStrokes(object device)
{
return this._strokes.ContainsKey(device) ? this._strokes[device] : null;
}
#region Event handle
protected override void OnPreviewTouchDown(TouchEventArgs e)
{
TouchPoint tp = e.GetTouchPoint(this);
if (this._inkCanvas.EditingMode == InkCanvasEditingMode.Ink)
{
this._startStroke(e.Device, tp.Position);
}
else
{
if (this._inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
{
this._removeStroke(e.Device, tp.Position);
}
}
e.Handled = true;
base.Focusable = true;
base.Focus();
base.Focusable = false;
e.TouchDevice.Capture(this);
}
protected override void OnPreviewTouchMove(TouchEventArgs e)
{
_handleTouchMove(e);
}
protected override void OnTouchUp(TouchEventArgs e)
{
e.TouchDevice.Capture(null); //
}
protected override void onm ouseDown(MouseButtonEventArgs e)
{
if (base.Visibility == System.Windows.Visibility.Visible)
{
if (this._inkCanvas.EditingMode == InkCanvasEditingMode.Ink)
{
this._startStroke(e.Device, e.GetPosition(this));
}
else
{
if (this._inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
{
this._removeStroke(e.Device, e.GetPosition(this));
}
}
e.MouseDevice.Capture(this);
}
}
protected override void onm ouseMove(MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
if (this._inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
{
this._removeStroke(e.Device, e.GetPosition(this));
return;
}
if (this._strokes.ContainsKey(e.Device) && this._currentStroke.ContainsKey(e.Device))
{
this._addPointToStroke(e.Device, e.GetPosition(this));
}
else
{
this._startStroke(e.Device, e.GetPosition(this));
}
}
}
protected override void onm ouseUp(MouseButtonEventArgs e)
{
e.MouseDevice.Capture(null);
}
#endregion
protected override Visual GetVisualChild(int index)
{
switch (index)
{
case 0: return this._inkCanvas;
case 1: return this.transparentOverlay;
default:
throw new ArgumentOutOfRangeException("index");
}
}
protected override Size MeasureOverride(Size availableSize)
{
this._inkCanvas.Measure(availableSize);
this.transparentOverlay.Measure(availableSize);
return this._inkCanvas.DesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
this._inkCanvas.Arrange(new Rect(finalSize));
this.transparentOverlay.Arrange(new Rect(finalSize));
return base.ArrangeOverride(finalSize);
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
base.AddVisualChild(this._inkCanvas);
base.AddVisualChild(this.transparentOverlay);
}
private void _handleTouchMove(TouchEventArgs e)
{
if(this._inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint){
this._removeStroke(e.Device , e.GetTouchPoint(this).Position);
e.Handled = true;
return ;
}
if(this._strokes.ContainsKey(e.Device) && this._currentStroke.ContainsKey(e.Device))
{
Stroke stroke = this._currentStroke[e.Device];
StylusPointCollection sps = stroke.StylusPoints;
if(sps != null){
TouchPoint tp = e.GetTouchPoint(this);
Point p = tp.Position;
this._addPointToStroke( e.Device , p);
}
}
else
{
TouchPoint tp = e.GetTouchPoint(this);
this._startStroke( e.Device ,tp.Position);
}
e.Handled = true;
}
private void _addPointToStroke(object device, Point position)
{
Stroke stroke = this._currentStroke[device];
if (stroke != null)
{
StylusPointCollection spc = stroke.StylusPoints;
if (spc != null)
{
spc.Add(new StylusPoint(position.X, position.Y, 0.5f));
}
}
}
private void _removeStroke(object device, Point position)
{
for (int i = 0; i < this._inkCanvas.Strokes.Count; i++)
{
Stroke stroke = this._inkCanvas.Strokes[i];
StrokeCollection sc = stroke.GetEraseResult(new Rect(position.X, position.Y, this._inkCanvas.DefaultDrawingAttributes.Width, this._inkCanvas.DefaultDrawingAttributes.Height));
this._inkCanvas.Strokes.Replace(stroke, sc);
}
}
private void _startStroke(object device, Point inputPosition)
{
StylusPointCollection stylusPointCollection = new StylusPointCollection();
stylusPointCollection.Add(new StylusPoint(inputPosition.X, inputPosition.Y, 0.5f));
if (stylusPointCollection.Count > 0)
{
Stroke stroke = new Stroke(stylusPointCollection);
stroke.DrawingAttributes.Width = this._inkCanvas.DefaultDrawingAttributes.Width;
stroke.DrawingAttributes.Height = this._inkCanvas.DefaultDrawingAttributes.Height;
stroke.DrawingAttributes.Color = this._inkCanvas.DefaultDrawingAttributes.Color;
this._inkCanvas.Strokes.Add(stroke);//添加到canvas
if (this._currentStroke.ContainsKey(device))
{
this._currentStroke.Remove(device);
}
this._currentStroke.Add(device, stroke);
if (this._strokes.ContainsKey(device))
{
this._strokes[device].Add(this._currentStroke[device]);
return;
}
this._strokes.Add(device, new StrokeCollection { this._currentStroke[device] });
}
}
private void InitInkCanvasPropertys(){
this._inkCanvas.Focusable = base.Focusable;
this._inkCanvas.Background = Brushes.Transparent;
this._inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
this._inkCanvas.UseCustomCursor = true;
}
}
添加辅助的代理类型
public enum StrokeType
{
Stroke,
HighlighterStroke,
EraseByPoint
}
public class InkCanvasProxy : InkCanvas
{
public InkCanvasProxy()
: base()
{
// base.IsHitTestVisible = false;
// base.StylusPlugIns.Remove(base.DynamicRenderer);
}
}
测试
<Window x:Class="Metro.G.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="600"
xmlns:ll="clr-namespace:Metro.G">
<Canvas Name="container" >
<ll:MultiTouchCanvas Width="600" Height="600" x:Name="_canvas"></ll:MultiTouchCanvas>
</Canvas>
</Window>
标签:inkCanvas,inkcanvas,触控,Device,base,._,device,wpf,DefaultDrawingAttributes
From: https://www.cnblogs.com/ives/p/18406324