本文是WPF学习11:基于MVVM Light 制作图形编辑工具(2)的后续

这一次的目标是完成

两个任务。

本节完成后的效果:

本文分为三个部分:

1.对之前代码不合理的地方重新设计。

2.图形可选择外框颜色,填充颜色的实现简介。

3.拖动图形的实现简介。


修改之前的代码

我们在写代码的时候,经常回头看之前的代码,如果觉得之前的代码有问题,这时候条件如果允许,就改了吧。

做出的改动:

1.修改Image为Canvas。

目的:使图形的缩放和移动这部分的代码实现大大简化。

去除了配置按钮。原因是:因为Image被换成了Canvas,更改画布大小的成本降低至接近0,直接把Canvas的宽高实现绑定就可以了。、

代码就不贴了,附件中有工程源码。


颜色部分

效果:

过程:首先是绑定颜色相关的List与属性。在前台代码中我们需要写好模板与绑定:

  1. <TextBlock VerticalAlignment="Center"><Run Text="外框颜色:"/></TextBlock>
  2. <ComboBox Width="100" Margin="0 0 10 0" ItemsSource="{Binding AvailableColors}" SelectedItem="{Binding BorderColor}">
  3. <ComboBox.ItemTemplate>
  4. <DataTemplate>
  5. <Rectangle Width="87" Height="15" Fill="{Binding}"/>
  6. </DataTemplate>
  7. </ComboBox.ItemTemplate>
  8. </ComboBox>
  9. <TextBlock VerticalAlignment="Center"><Run Text="填充颜色:"/></TextBlock>
  10. <ComboBox Width="100" Margin="0 0 10 0" ItemsSource="{Binding AvailableColors}" SelectedItem="{Binding BackGroundColor}">
  11. <ComboBox.ItemTemplate>
  12. <DataTemplate>
  13. <Rectangle Width="87" Height="15" Fill="{Binding}"/>
  14. </DataTemplate>
  15. </ComboBox.ItemTemplate>
  16. </ComboBox>

接下来,我们在ViewModel中要实现一个列表与两个颜色的属性,注意:ItemSource绑定的元素需要为Public的属性,不能是字段!

  1. private Brush _borderColor;
  2. public Brush BorderColor
  3. {
  4. get { return _borderColor; }
  5. set
  6. {
  7. _borderColor = value;
  8. RaisePropertyChanged("BorderColor");
  9. }
  10. }
  11.  
  12. private Brush _backGroundColor;
  13. public Brush BackGroundColor
  14. {
  15. get { return _backGroundColor; }
  16. set
  17. {
  18. _backGroundColor = value;
  19. RaisePropertyChanged("BackGroundColor");
  20. }
  21. }
  22.  
  23. public List<Brush> AvailableColors { get; set; }
  24.  
  25. /// <summary>
  26. /// Init property in ctor
  27. /// </summary>
  28. public MainViewModel()
  29. {
  30. AvailableColors = new List<Brush>()
  31. {
  32. new SolidColorBrush(Colors.Red),
  33. new SolidColorBrush(Colors.Black),
  34. new SolidColorBrush(Colors.Green),
  35. new SolidColorBrush(Color.FromRgb(1,180,255)),
  36. };
  37.  
  38. //Init default drawing size & Color
  39. DrawingAreaWidth = DrawingAreaHeight = 200;
  40. BackGroundColor = BorderColor = AvailableColors[0];
  41. }

如图,到了这一步,数据绑定就完成啦。

通过BackGroundColor,BorderColor我们又可以拿到选定的颜色,在后台代码中,画图时,把它们用上就好了。代码位于附件。


拖动部分

新建类ShapeManagement 由它来管理缩放与移动。

  1. class ShapeManagement
  2. {
  3. private Shape previseSelectedShape;
  4. private Brush previseSelectedShapeBrush;
  5. //使被选中的图形呈现橘黄色
  6. private Brush selectedBrush = Brushes.Orange;
  7. public void SelectedChange(Shape shape)
  8. {
  9. ClearSelectedEffect();
  10. previseSelectedShape = shape;
  11. previseSelectedShapeBrush = previseSelectedShape.Fill.Clone();
  12. previseSelectedShape.Fill = selectedBrush;
  13. }
  14.  
  15. public void ClearSelectedEffect()
  16. {
  17. if (previseSelectedShape != null)
  18. previseSelectedShape.Fill = previseSelectedShapeBrush;
  19. }
  20. }

在ViewModel创建一个图形管理器:

  1. private ShapeManagement shapeManagement = new ShapeManagement();

在MouseDown中加入如下代码:

  1. if(MovingModeEnable)
  2. {
  3. if (e.Source is Shape)
  4. shapeManagement.SelectedChange(e.Source as Shape);
  5. else if(e.Source is Panel)
  6. shapeManagement.ClearSelectedEffect();
  7. }

如图,我们现在可以拿到被点击的对象

之后就是移动的部分,在ShapeManagement加入如下代码:

  1. class ShapeItem
  2. {
  3. public Shape DisplayShape { get; set; }
  4. public TranslateTransform translateTransform { get; set; }
  5. public Point PositonRecord { get; set; }
  6. public Point HistoryPositonRecord { get; set; }
  7. }
  8.  
  9. private List<ShapeItem> shapeList = new List<ShapeItem>();
  10.  
  11. public void Add(Shape shape)
  12. {
  13. var shapeItem = new ShapeItem()
  14. {
  15. DisplayShape = shape,
  16. translateTransform = new TranslateTransform(),
  17. PositonRecord = new Point(),
  18. HistoryPositonRecord = new Point()
  19. };
  20. shapeList.Add(shapeItem);
  21. shape.RenderTransform = new TransformGroup()
  22. {
  23. Children = new TransformCollection() { shapeItem.translateTransform }
  24. };
  25. }

之前,我们已经拿到了当前选中的对象,然后就可以根据LINQ查询,来操作该对象,找到相应的变形,点的信息,予以操作。

代码在附件中,目前还有一些BUG。

开发环境VS2013, .NET4.5。

源码

  1.  

WPF学习12:基于MVVM Light 制作图形编辑工具(3)的更多相关文章

  1. WPF学习11:基于MVVM Light 制作图形编辑工具(2)

    本文是WPF学习10:基于MVVM Light 制作图形编辑工具(1)的后续 这一次的目标是完成 两个任务. 画布 效果: 画布上,选择的方案是:直接以Image作为画布,使用RenderTarget ...

  2. WPF学习10:基于MVVM Light 制作图形编辑工具(1)

    图形编辑器的功能如下图所示: 除了MVVM Light 框架是一个新东西之外,本文所涉及内容之前的WPF学习0-9基本都有相关介绍. 本节中,将搭建编辑器的界面,搭建MVVM Light 框架的使用环 ...

  3. WPF学习笔记-用Expression Design制作矢量图然后导出为XAML

    WPF学习笔记-用Expression Design制作矢量图然后导出为XAML 第一次用Windows live writer写东西,感觉不错,哈哈~~ 1.在白纸上完全凭感觉,想象来画图难度很大, ...

  4. WPF学习08:MVVM 预备知识之COMMAND

    WPF内建的COMMAND是GOF 提出的23种设计模式中,命令模式的实现. 本文是WPF学习07:MVVM 预备知识之数据绑定的后续,将说明实现COMMAND的三个重点:ICommand  Comm ...

  5. 【Telerik控件学习】-建立自己的图形编辑工具(Diagram)

    Telerik提供了RadDiagram控件,用于图形元素的旋转,拖拽和缩放.更重要的是,它还拓展了许多绑定的命令(复制,剪切,粘贴,回退等等). 我们可以用来组织自己的图形编辑工具. Step1.定 ...

  6. MAPZONE GIS SDK接入Openlayers3之五——图形编辑工具

    图形编辑工具提供对要素图形进行增.删.改的功能,具体包括以下几种工具类型: 浏览工具 选择工具 创建要素工具 删除命令 分割工具 合并命令 节点编辑工具 修边工具 撤销命令 重做命令 工具的实现基本上 ...

  7. WPF学习07:MVVM 预备知识之数据绑定

    MVVM是一种模式,而WPF的数据绑定机制是一种WPF内建的功能集,两者是不相关的. 但是,借助WPF各种内建功能集,如数据绑定.命令.数据模板,我们可以高效的在WPF上实现MVVM.因此,我们需要对 ...

  8. WPF学习笔记-用Expression Blend制作自定义按钮

    1.从Blend工具箱中添加一个Button,按住shift,将尺寸调整为125*125; 2.右键点击此按钮,选择Edit control parts(template)>Edit a cop ...

  9. WPF学习笔记:MVVM模式下,ViewModel如何关闭View?

    原文:http://blog.csdn.net/leftfist/article/details/32349731 矫枉过正,从一个极端走向另一个极端.MVVM模式,View只负责呈现,虽然也有后台代 ...

随机推荐

  1. RFC外部断点在在SAP退出后会失效

    rfc外部断点系统退出后会删除吗?  不会删除Rfc外部断点在在SAP退出后标识还在, 但是断点会失效! 附 断点消息: ABAP 中的断点分为静态和动态两种.一. 静态断点(Static Break ...

  2. 安装mysql 8.0版本时,使用front连接报1251错误或者navicat 连接报错2059解决方案

    这个错误出现的原因是在mysql8之前的版本中加密规则为mysql_native_password,而在mysql8以后的加密规则为caching_sha2_password. 解决此问题有两种方法, ...

  3. Tomcat 系统架构与设计模式之二

    Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析 来自:http://www.ibm.com/developerworks/cn/java/j-lo-tomcat2/ 这个分为两个部分的 ...

  4. Android 动态注册 亮屏、息屏广播

    /***************************************************************************** * Android 动态注册 亮屏.息屏广 ...

  5. 「LuoguP3369」 【模板】普通平衡树 (用vector乱搞平衡树

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入 x 数 删除 x 数(若有多个相同的数,应只删除一个) 查询 x 数的排名(排名定义为比当前 ...

  6. Python Web开发最难懂的WSGI协议,到底包含哪些内容?

    原文出处: PythonScientists 我想大部分Python开发者最先接触到的方向是WEB方向(因为总是有开发者希望马上给自己做个博客出来,例如我),既然是WEB,免不了接触到一些WEB框架, ...

  7. Linux下PostgreSQL 的安装与配置

    一.简介 PostgreSQL 是一种非常复杂的对象-关系型数据库管理系统(ORDBMS),也是目前功能最强大,特性最丰富和最复杂的自由软件数据库系统.有些特性甚至连商业数据库都不具备.这个起源于伯克 ...

  8. public void与public static void区别

    我们换个简单易懂的说法,这两句的区别就在于,能不能直接用类名访问. 很好理解的不是吗? 假如,我有一个类,如下图所示: 接下来先实例化一个对象,ca,你会发现它不仅可以访问普通的方法,也可以访问静态的 ...

  9. A. Vanya and Table

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  10. View Controller Programming Guide for iOS---(三)---Using View Controllers in Your App

    Using View Controllers in Your App Whether you are working with view controllers provided by iOS, or ...