[源码下载]
稳扎稳打Silverlight(14) - 2.0交互之InkPresenter(涂鸦板)
作者: webabcd
介绍
Silverlight 2.0 人机交互:InkPresenter(涂鸦板)
InkPresenter - 涂鸦板,也就是在面板上呈现墨迹。InkPresenter 可以包含子控件
Cursor - 鼠标移动到 InkPresenter 上面时,鼠标指针的样式
Background - 涂鸦板背景
Opacity - 面板上墨迹的不透明度
Clip - InkPresenter 的剪辑区域
Stroke.DrawingAttributes - Stroke(笔划)的外观属性
UIElement.CaptureMouse() - 为 UIElement 对象启用鼠标捕捉
UIElement.ReleaseMouseCapture() - 为 UIElement 对象释放鼠标捕捉
在线DEMO
http://www.cnblogs.com/webabcd/archive/2008/10/09/1307486.html
示例
InkPresenter.xaml
<
UserControl
x:Class
="Silverlight20.Interactive.InkPresenter"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d ="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable ="d" >
< Canvas >
<!-- InkPresenter 的外围的带边框的背景图 -->
< Rectangle Width ="420" Height ="350" Stroke ="Black" StrokeThickness ="1" >
< Rectangle.Fill >
< ImageBrush ImageSource ="/Silverlight20;component/Images/Background.jpg" Stretch ="Fill" />
</ Rectangle.Fill >
</ Rectangle >
<!-- 用于描绘 InkPresenter 的工作区 -->
< Rectangle Canvas.Top ="10" Canvas.Left ="10" Width ="400" Height ="300" RadiusX ="25" RadiusY ="25" Fill ="Black" Opacity ="0.2" />
<!--
InkPresenter - 涂鸦板,也就是在面板上呈现墨迹
Cursor - 鼠标移动到 InkPresenter 上面时,鼠标指针的样式
Arrow - 箭头
Hand - 手形
Wait - 沙漏
IBeam - “I”字形
Stylus - 点
Eraser - 橡皮
None - 无
Background - 涂鸦板背景。建议设置其为“Transparent”,需要的话可以使用其他控件来描绘背景
Opacity - 面板上墨迹的不透明度
Clip - InkPresenter 的剪辑区域。本例给 InkPresenter 做了一个圆角效果,其Clip值由 Blend 生成
-->
< InkPresenter x:Name ="inkPresenter" Cursor ="Stylus" Canvas.Top ="10" Canvas.Left ="10" Width ="400" Height ="300" Background ="Transparent"
MouseLeftButtonDown ="inkPresenter_MouseLeftButtonDown"
MouseLeftButtonUp ="inkPresenter_MouseLeftButtonUp"
MouseMove ="inkPresenter_MouseMove"
Clip ="M0.5,25.5 C0.5,11.692882 11.692882,0.5 25.5,0.5 L374.5,0.5 C388.30713,0.5 399.5,11.692882 399.5,25.5 L399.5,274.5 C399.5,288.30713 388.30713,299.5 374.5,299.5 L25.5,299.5 C11.692882,299.5 0.5,288.30713 0.5,274.5 z" >
<!--
InkPresenter 可以包含子控件。本例为在 InkPresenter 的底部循环播放视频
-->
< MediaElement x:Name ="mediaElement" Source ="/Silverlight20;component/Video/Demo.wmv" Width ="400" Height ="100" Canvas.Top ="200" Stretch ="UniformToFill" MediaEnded ="mediaElement_MediaEnded" />
</ InkPresenter >
<!-- 红色取色点,点此后可画红色的线 -->
< Ellipse x:Name ="ellipseRed" Canvas.Top ="320" Canvas.Left ="20" Cursor ="Hand" Fill ="Red" Width ="20" Height ="20" MouseLeftButtonDown ="ellipseRed_MouseLeftButtonDown" />
<!-- 黑色取色点,点此后可画黑色的线 -->
< Ellipse x:Name ="ellipseBlack" Canvas.Top ="320" Canvas.Left ="50" Cursor ="Hand" Fill ="Black" Width ="20" Height ="20" MouseLeftButtonDown ="ellipseBlack_MouseLeftButtonDown" />
<!-- 橡皮擦,点此后可擦除之前画的线 -->
< Button x:Name ="btnEraser" Canvas.Top ="320" Canvas.Left ="80" Content ="橡皮擦" Click ="btnEraser_Click" />
<!-- 用于清除 InkPresenter 上的墨迹的按钮 -->
< Button x:Name ="btnClear" Canvas.Top ="320" Canvas.Left ="130" Content ="清除" Click ="btnClear_Click" />
<!-- 用于显示当前 Stroke(笔划) 所在的 矩形范围 的位置信息 -->
< TextBox x:Name ="txtMsg" Canvas.Top ="320" Canvas.Left ="180" Width ="220" />
</ Canvas >
</ UserControl >
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d ="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable ="d" >
< Canvas >
<!-- InkPresenter 的外围的带边框的背景图 -->
< Rectangle Width ="420" Height ="350" Stroke ="Black" StrokeThickness ="1" >
< Rectangle.Fill >
< ImageBrush ImageSource ="/Silverlight20;component/Images/Background.jpg" Stretch ="Fill" />
</ Rectangle.Fill >
</ Rectangle >
<!-- 用于描绘 InkPresenter 的工作区 -->
< Rectangle Canvas.Top ="10" Canvas.Left ="10" Width ="400" Height ="300" RadiusX ="25" RadiusY ="25" Fill ="Black" Opacity ="0.2" />
<!--
InkPresenter - 涂鸦板,也就是在面板上呈现墨迹
Cursor - 鼠标移动到 InkPresenter 上面时,鼠标指针的样式
Arrow - 箭头
Hand - 手形
Wait - 沙漏
IBeam - “I”字形
Stylus - 点
Eraser - 橡皮
None - 无
Background - 涂鸦板背景。建议设置其为“Transparent”,需要的话可以使用其他控件来描绘背景
Opacity - 面板上墨迹的不透明度
Clip - InkPresenter 的剪辑区域。本例给 InkPresenter 做了一个圆角效果,其Clip值由 Blend 生成
-->
< InkPresenter x:Name ="inkPresenter" Cursor ="Stylus" Canvas.Top ="10" Canvas.Left ="10" Width ="400" Height ="300" Background ="Transparent"
MouseLeftButtonDown ="inkPresenter_MouseLeftButtonDown"
MouseLeftButtonUp ="inkPresenter_MouseLeftButtonUp"
MouseMove ="inkPresenter_MouseMove"
Clip ="M0.5,25.5 C0.5,11.692882 11.692882,0.5 25.5,0.5 L374.5,0.5 C388.30713,0.5 399.5,11.692882 399.5,25.5 L399.5,274.5 C399.5,288.30713 388.30713,299.5 374.5,299.5 L25.5,299.5 C11.692882,299.5 0.5,288.30713 0.5,274.5 z" >
<!--
InkPresenter 可以包含子控件。本例为在 InkPresenter 的底部循环播放视频
-->
< MediaElement x:Name ="mediaElement" Source ="/Silverlight20;component/Video/Demo.wmv" Width ="400" Height ="100" Canvas.Top ="200" Stretch ="UniformToFill" MediaEnded ="mediaElement_MediaEnded" />
</ InkPresenter >
<!-- 红色取色点,点此后可画红色的线 -->
< Ellipse x:Name ="ellipseRed" Canvas.Top ="320" Canvas.Left ="20" Cursor ="Hand" Fill ="Red" Width ="20" Height ="20" MouseLeftButtonDown ="ellipseRed_MouseLeftButtonDown" />
<!-- 黑色取色点,点此后可画黑色的线 -->
< Ellipse x:Name ="ellipseBlack" Canvas.Top ="320" Canvas.Left ="50" Cursor ="Hand" Fill ="Black" Width ="20" Height ="20" MouseLeftButtonDown ="ellipseBlack_MouseLeftButtonDown" />
<!-- 橡皮擦,点此后可擦除之前画的线 -->
< Button x:Name ="btnEraser" Canvas.Top ="320" Canvas.Left ="80" Content ="橡皮擦" Click ="btnEraser_Click" />
<!-- 用于清除 InkPresenter 上的墨迹的按钮 -->
< Button x:Name ="btnClear" Canvas.Top ="320" Canvas.Left ="130" Content ="清除" Click ="btnClear_Click" />
<!-- 用于显示当前 Stroke(笔划) 所在的 矩形范围 的位置信息 -->
< TextBox x:Name ="txtMsg" Canvas.Top ="320" Canvas.Left ="180" Width ="220" />
</ Canvas >
</ UserControl >
InkPresenter.xaml.cs
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Ink;
using System.Xml.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace Silverlight20.Interactive
{
public partial class InkPresenter : UserControl
{
// 在涂鸦板上描绘的笔划
private System.Windows.Ink.Stroke _newStroke;
// 在涂鸦板上描绘的笔划的颜色
private System.Windows.Media.Color _currentColor = Colors.Red;
// 是否是擦除操作
private bool _isEraser = false;
// 当前是否正在 InkPresenter 上捕获鼠标
private bool _isCapture = false;
public InkPresenter()
{
InitializeComponent();
}
void inkPresenter_MouseLeftButtonDown(object sender, MouseEventArgs e)
{
// UIElement.CaptureMouse() - 为 UIElement 对象启用鼠标捕捉
// 为 InkPresenter 启用鼠标捕捉
inkPresenter.CaptureMouse();
_isCapture = true;
if (_isEraser)
{
// 擦除鼠标当前位置所属的 Stroke(笔划)
RemoveStroke(e);
}
else
{
// System.Windows.Input.MouseEventArgs.StylusDevice.Inverted - 是否正在使用手写笔(tablet pen)的辅助笔尖
// System.Windows.Ink.Stroke.DrawingAttributes - Stroke(笔划)的外观属性
// System.Windows.Ink.Stroke.DrawingAttributes.Width - 笔划的宽
// System.Windows.Ink.Stroke.DrawingAttributes.Height - 笔划的高
// System.Windows.Ink.Stroke.DrawingAttributes.Color - 笔划的颜色
// System.Windows.Ink.Stroke.DrawingAttributes.OutlineColor - 笔划的外框的颜色
_newStroke = new System.Windows.Ink.Stroke();
_newStroke.DrawingAttributes.Width = 3d;
_newStroke.DrawingAttributes.Height = 3d;
_newStroke.DrawingAttributes.Color = _currentColor;
_newStroke.DrawingAttributes.OutlineColor = Colors.Yellow;
// 为 Stroke(笔划) 在当前鼠标所在位置处增加 StylusPoint(点)
_newStroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(inkPresenter));
// 将设置好的 Stroke(笔划) 添加到 InkPresenter 的 Strokes(笔划集) 中
inkPresenter.Strokes.Add(_newStroke);
// Stroke.GetBounds() - 获取当前 Stroke(笔划) 所在的 矩形范围 的位置信息
// Strokes.GetBounds() - 获取当前 Strokes(笔划集) 所在的 矩形范围 的位置信息
// 显示该 Stroke(笔划) 所在的 矩形范围 的位置信息
Rect rect = _newStroke.GetBounds();
txtMsg.Text = string.Format("上:{0}; 下:{1}; 左:{2}; 右:{3}",
rect.Top, rect.Bottom, rect.Left, rect.Right);
}
}
void inkPresenter_MouseMove(object sender, MouseEventArgs e)
{
if (_isCapture)
{
if (_isEraser)
{
// 擦除鼠标当前位置所属的 Stroke
RemoveStroke(e);
}
else if (_newStroke != null)
{
// 为已经添加到 InkPresenter 的 Strokes 中的 Stroke 增加 StylusPoint
_newStroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(inkPresenter));
// 显示该 Stroke 所在的 矩形范围 的位置信息
Rect rect = _newStroke.GetBounds();
txtMsg.Text = string.Format("上:{0}; 下:{1}; 左:{2}; 右:{3}",
rect.Top, rect.Bottom, rect.Left, rect.Right);
}
}
}
void inkPresenter_MouseLeftButtonUp(object sender, MouseEventArgs e)
{
// UIElement.CaptureMouse() - 为 UIElement 对象释放鼠标捕捉
// 为 InkPresenter 释放鼠标捕捉
inkPresenter.ReleaseMouseCapture();
_newStroke = null;
_isCapture = false;
}
void RemoveStroke(MouseEventArgs e)
{
// Stroke.HitTest(StylusPointCollection) - Stroke 是否与指定的 StylusPoint 集合相连
// Strokes.HitTest(StylusPointCollection) - 与指定的 StylusPoint 集合相连的 Stroke 集合
// 获取当前鼠标所在位置处的 StylusPoint 集合
StylusPointCollection erasePoints = new StylusPointCollection();
erasePoints.Add(e.StylusDevice.GetStylusPoints(inkPresenter));
// 与当前鼠标所在位置处的 StylusPoint 集合相连的 Stroke 集合
StrokeCollection hitStrokes = inkPresenter.Strokes.HitTest(erasePoints);
for (int i = 0; i < hitStrokes.Count; i++)
{
// 在 InkPresenter 上清除指定的 Stroke
inkPresenter.Strokes.Remove(hitStrokes[i]);
}
}
private void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
{
// 视频播放完后,再重新播放
mediaElement.Position = TimeSpan.FromMilliseconds(0);
mediaElement.Play();
}
private void ellipseRed_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// 单击了 红色取色点
_currentColor = Colors.Red;
inkPresenter.Cursor = Cursors.Stylus;
_isEraser = false;
}
private void ellipseBlack_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// 单击了 黑色取色点
_currentColor = Colors.Black;
inkPresenter.Cursor = Cursors.Stylus;
_isEraser = false;
}
private void btnClear_Click(object sender, RoutedEventArgs e)
{
// 单击了 清除 按钮
inkPresenter.Strokes.Clear();
}
private void btnEraser_Click(object sender, RoutedEventArgs e)
{
// 单击了 橡皮擦 按钮
inkPresenter.Cursor = Cursors.Eraser;
_isEraser = true;
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Ink;
using System.Xml.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace Silverlight20.Interactive
{
public partial class InkPresenter : UserControl
{
// 在涂鸦板上描绘的笔划
private System.Windows.Ink.Stroke _newStroke;
// 在涂鸦板上描绘的笔划的颜色
private System.Windows.Media.Color _currentColor = Colors.Red;
// 是否是擦除操作
private bool _isEraser = false;
// 当前是否正在 InkPresenter 上捕获鼠标
private bool _isCapture = false;
public InkPresenter()
{
InitializeComponent();
}
void inkPresenter_MouseLeftButtonDown(object sender, MouseEventArgs e)
{
// UIElement.CaptureMouse() - 为 UIElement 对象启用鼠标捕捉
// 为 InkPresenter 启用鼠标捕捉
inkPresenter.CaptureMouse();
_isCapture = true;
if (_isEraser)
{
// 擦除鼠标当前位置所属的 Stroke(笔划)
RemoveStroke(e);
}
else
{
// System.Windows.Input.MouseEventArgs.StylusDevice.Inverted - 是否正在使用手写笔(tablet pen)的辅助笔尖
// System.Windows.Ink.Stroke.DrawingAttributes - Stroke(笔划)的外观属性
// System.Windows.Ink.Stroke.DrawingAttributes.Width - 笔划的宽
// System.Windows.Ink.Stroke.DrawingAttributes.Height - 笔划的高
// System.Windows.Ink.Stroke.DrawingAttributes.Color - 笔划的颜色
// System.Windows.Ink.Stroke.DrawingAttributes.OutlineColor - 笔划的外框的颜色
_newStroke = new System.Windows.Ink.Stroke();
_newStroke.DrawingAttributes.Width = 3d;
_newStroke.DrawingAttributes.Height = 3d;
_newStroke.DrawingAttributes.Color = _currentColor;
_newStroke.DrawingAttributes.OutlineColor = Colors.Yellow;
// 为 Stroke(笔划) 在当前鼠标所在位置处增加 StylusPoint(点)
_newStroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(inkPresenter));
// 将设置好的 Stroke(笔划) 添加到 InkPresenter 的 Strokes(笔划集) 中
inkPresenter.Strokes.Add(_newStroke);
// Stroke.GetBounds() - 获取当前 Stroke(笔划) 所在的 矩形范围 的位置信息
// Strokes.GetBounds() - 获取当前 Strokes(笔划集) 所在的 矩形范围 的位置信息
// 显示该 Stroke(笔划) 所在的 矩形范围 的位置信息
Rect rect = _newStroke.GetBounds();
txtMsg.Text = string.Format("上:{0}; 下:{1}; 左:{2}; 右:{3}",
rect.Top, rect.Bottom, rect.Left, rect.Right);
}
}
void inkPresenter_MouseMove(object sender, MouseEventArgs e)
{
if (_isCapture)
{
if (_isEraser)
{
// 擦除鼠标当前位置所属的 Stroke
RemoveStroke(e);
}
else if (_newStroke != null)
{
// 为已经添加到 InkPresenter 的 Strokes 中的 Stroke 增加 StylusPoint
_newStroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(inkPresenter));
// 显示该 Stroke 所在的 矩形范围 的位置信息
Rect rect = _newStroke.GetBounds();
txtMsg.Text = string.Format("上:{0}; 下:{1}; 左:{2}; 右:{3}",
rect.Top, rect.Bottom, rect.Left, rect.Right);
}
}
}
void inkPresenter_MouseLeftButtonUp(object sender, MouseEventArgs e)
{
// UIElement.CaptureMouse() - 为 UIElement 对象释放鼠标捕捉
// 为 InkPresenter 释放鼠标捕捉
inkPresenter.ReleaseMouseCapture();
_newStroke = null;
_isCapture = false;
}
void RemoveStroke(MouseEventArgs e)
{
// Stroke.HitTest(StylusPointCollection) - Stroke 是否与指定的 StylusPoint 集合相连
// Strokes.HitTest(StylusPointCollection) - 与指定的 StylusPoint 集合相连的 Stroke 集合
// 获取当前鼠标所在位置处的 StylusPoint 集合
StylusPointCollection erasePoints = new StylusPointCollection();
erasePoints.Add(e.StylusDevice.GetStylusPoints(inkPresenter));
// 与当前鼠标所在位置处的 StylusPoint 集合相连的 Stroke 集合
StrokeCollection hitStrokes = inkPresenter.Strokes.HitTest(erasePoints);
for (int i = 0; i < hitStrokes.Count; i++)
{
// 在 InkPresenter 上清除指定的 Stroke
inkPresenter.Strokes.Remove(hitStrokes[i]);
}
}
private void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
{
// 视频播放完后,再重新播放
mediaElement.Position = TimeSpan.FromMilliseconds(0);
mediaElement.Play();
}
private void ellipseRed_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// 单击了 红色取色点
_currentColor = Colors.Red;
inkPresenter.Cursor = Cursors.Stylus;
_isEraser = false;
}
private void ellipseBlack_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// 单击了 黑色取色点
_currentColor = Colors.Black;
inkPresenter.Cursor = Cursors.Stylus;
_isEraser = false;
}
private void btnClear_Click(object sender, RoutedEventArgs e)
{
// 单击了 清除 按钮
inkPresenter.Strokes.Clear();
}
private void btnEraser_Click(object sender, RoutedEventArgs e)
{
// 单击了 橡皮擦 按钮
inkPresenter.Cursor = Cursors.Eraser;
_isEraser = true;
}
}
}
OK
[源码下载]