zoukankan      html  css  js  c++  java
  • 稳扎稳打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
    [源码下载]
  • 相关阅读:
    【BZOJ 4581】【Usaco2016 Open】Field Reduction
    【BZOJ 4582】【Usaco2016 Open】Diamond Collector
    【BZOJ 4580】【Usaco2016 Open】248
    【BZOJ 3754】Tree之最小方差树
    【51Nod 1501】【算法马拉松 19D】石头剪刀布威力加强版
    【51Nod 1622】【算法马拉松 19C】集合对
    【51Nod 1616】【算法马拉松 19B】最小集合
    【51Nod 1674】【算法马拉松 19A】区间的价值 V2
    【BZOJ 2541】【Vijos 1366】【CTSC 2000】冰原探险
    【BZOJ 1065】【Vijos 1826】【NOI 2008】奥运物流
  • 原文地址:https://www.cnblogs.com/webabcd/p/1334768.html
Copyright © 2011-2022 走看看