• 稳扎稳打Silverlight(14) 2.0交互之InkPresenter(涂鸦板)


    [索引页]
    [源码下载]


    稳扎稳打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>

    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;
            }

        }

    }



    OK
    [源码下载]
  • 相关阅读:
    010 --- 第14章 观察者模式
    009 --- 第13章 建造者模式
    008 --- 第12章 外观模式
    007 --- 第10章 模板方法模式
    006 --- 第9章 原型模式
    redis lua 中keys[1] 和argv[1] 的理解
    redis 入门总结
    mysql 8.0 特性简单总结
    MySql事务隔离级别 浅见
    浅谈Java中的String、StringBuffer、StringBuilder
  • 原文地址:https://www.cnblogs.com/webabcd/p/1334768.html
Copyright © 2020-2023  润新知