WPF:使用鼠标在Canvas面板上画线
2015-09-08 15:13
567 查看
使用Canvas+Line 任意画线
主要使用布局面板Canvas作为背景,通过其属性Children添加Line 来实现画线。可以理解为 每一个Line 就是一个点。不清楚Canvas的用法可以参见:点击打开链接 Line的参见:点击打开链接
操作效果
按下鼠标左键任意画线,可以修改线的颜色(红色,绿色)修改线的样式(实线,虚线)。后期增加导出生成图片功能。
代码解析
线由点组成,当然我这里的点其实就是线。线由开始点与结束点构成,想必看到过msdn上line的解释就会一目了然。至于鼠标事件,会有鼠标左键按下以及移动,松开动作。 还需要有个一集合来存放点,取名为List<Point> 类型。 在鼠标按下事件中可以这样写:/// <summary> /// 起始位置 /// </summary> Point startPoint; /// <summary> /// 点集合 /// </summary> List<Point> pointList = new List<Point>(); /// <summary> /// 鼠标左键按下获取开始Point /// </summary> private void Canvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { startPoint = e.GetPosition(myCanvas); }记录开始位置startPoint 。按下之后随之的就是Move动作,在移动事件中这样写:
/// <summary> /// 按下鼠标左键移动 /// </summary> private void Canvas_PreviewMouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { // 返回指针相对于Canvas的位置 Point point = e.GetPosition(myCanvas); if (pointList.Count == 0) { // 加入起始点 pointList.Add(new Point(this.startPoint.X, this.startPoint.Y)); } else { // 加入移动过程中的point pointList.Add(point); } // 去重复点 var disList = pointList.Distinct().ToList(); var count = disList.Count(); // 总点数 if (point != this.startPoint && this.startPoint != null) { var l = new Line(); string color = (cboColor.SelectedItem as ComboBoxItem).Content as string; if (color == "默认") { l.Stroke = Brushes.Black; } if (color == "红色") { l.Stroke = Brushes.Red; } if (color == "绿色") { l.Stroke = Brushes.Green; } l.StrokeThickness = 1; if (count < 2) return; l.X1 = disList[count - 2].X; // count-2 保证 line的起始点为点集合中的倒数第二个点。 l.Y1 = disList[count - 2].Y; // 终点X,Y 为当前point的X,Y l.X2 = point.X; l.Y2 = point.Y; myCanvas.Children.Add(l); } } }
移动过程中创建Line对象并加入Canvas中。 代码中的颜色判断最好修改成枚举类型。
修改线颜色及样式
这部分比较简单,直接遍历Canvas中的Line对象,修改Line的Stroke属性,StrokeDashArray属性。/// <summary> /// 选择颜色 /// </summary> private void cboColor_SelectionChanged(object sender, SelectionChangedEventArgs e) { string color = (cboColor.SelectedItem as ComboBoxItem).Content as string; if (this.myCanvas != null) { List<Line> list = GetChildObjects<Line>(this.myCanvas); if (list.Count > 0) { list.ForEach(l => { if (color == "默认") { l.Stroke = Brushes.Black; } if (color == "红色") { l.Stroke = Brushes.Red; } if (color == "绿色") { l.Stroke = Brushes.Green; } }); list.Clear(); } } }
/// <summary> /// 选择style /// </summary> private void cboStyle_SelectionChanged(object sender, SelectionChangedEventArgs e) { string style = (cboStyle.SelectedItem as ComboBoxItem).Content as string; if (this.myCanvas == null) { return; } List<Line> list = GetChildObjects<Line>(this.myCanvas); if (list.Count > 0) { list.ForEach(l => { if (style == "默认") { l.StrokeDashArray = new DoubleCollection(new List<double>() { }); } if (style == "虚线") { l.StrokeDashArray = new DoubleCollection(new List<double>() { 1,1,1,1 }); } }); list.Clear(); } }
GetChildObjects 方法参见博客文章。
前台XAML
主要用到了WrapPanel,StackPanel布局控件。<WrapPanel> <StackPanel> <WrapPanel> <Label Content="颜色:" VerticalAlignment="Center"></Label> <ComboBox x:Name="cboColor" SelectedIndex="0" Width="120" Margin="10" SelectionChanged="cboColor_SelectionChanged"> <ComboBoxItem>默认</ComboBoxItem> <ComboBoxItem>红色</ComboBoxItem> <ComboBoxItem>绿色</ComboBoxItem> </ComboBox> </WrapPanel> <WrapPanel> <Label Content="样式:" VerticalAlignment="Center"></Label> <ComboBox x:Name="cboStyle" Width="120" Margin="10" SelectionChanged="cboStyle_SelectionChanged"> <ComboBoxItem IsSelected="True">默认</ComboBoxItem> <ComboBoxItem>虚线</ComboBoxItem> </ComboBox> </WrapPanel> </StackPanel> <Canvas Width="500" Height="500" Background="Gray" x:Name="myCanvas" PreviewMouseLeftButtonDown="Canvas_PreviewMouseLeftButtonDown" PreviewMouseMove="Canvas_PreviewMouseMove"> </Canvas> </WrapPanel>
相关文章推荐
- Direct2D+MFC学习笔记
- expect中的close,wait,exit,return
- JSON转换工具:fastjson与jackson
- python可变长参数
- WebView
- android 组件设置屏幕大小
- AWK print学习
- 15_09_08 Eclipse导入Android时出现红色感叹号的异常
- MFC改变static text颜色和内容
- swift 下拉图片变大 coreData 声明数组变量
- 微信公众帐号开发教程第10篇-解析接口中的消息创建时间CreateTime
- 今天看了一个利用MYeclipse进行Struts讲解的视频和大家分享一下
- redis剖析(一)redis性能
- codeforces 267A A. Subtractions(辗转相除)
- 零基础学python-12.5 修改列表的误区以及使用for和range修改列表
- 零基础学python-12.5 修改列表的误区以及使用for和range修改列表
- 把linux的man手册转化为windows下可读的格式
- cocos2d-x 接入android ,登录第三方SDK时屏幕不断闪烁刷屏的问题解决
- 微信公众帐号开发教程第9篇-QQ表情的发送与接收
- MongoDB 索引简单使用技巧