本文是WPF學習11:基於MVVM Light 制作圖形編輯工具(2)的后續
兩個任務。
本節完成后的效果:
本文分為三個部分:
1.對之前代碼不合理的地方重新設計。
2.圖形可選擇外框顏色,填充顏色的實現簡介。
3.拖動圖形的實現簡介。
修改之前的代碼
我們在寫代碼的時候,經常回頭看之前的代碼,如果覺得之前的代碼有問題,這時候條件如果允許,就改了吧。
做出的改動:
1.修改Image為Canvas。
目的:使圖形的縮放和移動這部分的代碼實現大大簡化。
去除了配置按鈕。原因是:因為Image被換成了Canvas,更改畫布大小的成本降低至接近0,直接把Canvas的寬高實現綁定就可以了。、
代碼就不貼了,附件中有工程源碼。
顏色部分
過程:首先是綁定顏色相關的List與屬性。在前台代碼中我們需要寫好模板與綁定:
<TextBlock VerticalAlignment="Center"><Run Text="外框顏色:"/></TextBlock> <ComboBox Width="100" Margin="0 0 10 0" ItemsSource="{Binding AvailableColors}" SelectedItem="{Binding BorderColor}"> <ComboBox.ItemTemplate> <DataTemplate> <Rectangle Width="87" Height="15" Fill="{Binding}"/> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> <TextBlock VerticalAlignment="Center"><Run Text="填充顏色:"/></TextBlock> <ComboBox Width="100" Margin="0 0 10 0" ItemsSource="{Binding AvailableColors}" SelectedItem="{Binding BackGroundColor}"> <ComboBox.ItemTemplate> <DataTemplate> <Rectangle Width="87" Height="15" Fill="{Binding}"/> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox>
接下來,我們在ViewModel中要實現一個列表與兩個顏色的屬性,注意:ItemSource綁定的元素需要為Public的屬性,不能是字段!
private Brush _borderColor; public Brush BorderColor { get { return _borderColor; } set { _borderColor = value; RaisePropertyChanged("BorderColor"); } } private Brush _backGroundColor; public Brush BackGroundColor { get { return _backGroundColor; } set { _backGroundColor = value; RaisePropertyChanged("BackGroundColor"); } } public List<Brush> AvailableColors { get; set; } /// <summary> /// Init property in ctor /// </summary> public MainViewModel() { AvailableColors = new List<Brush>() { new SolidColorBrush(Colors.Red), new SolidColorBrush(Colors.Black), new SolidColorBrush(Colors.Green), new SolidColorBrush(Color.FromRgb(1,180,255)), }; //Init default drawing size & Color DrawingAreaWidth = DrawingAreaHeight = 200; BackGroundColor = BorderColor = AvailableColors[0]; }
通過BackGroundColor,BorderColor我們又可以拿到選定的顏色,在后台代碼中,畫圖時,把它們用上就好了。代碼位於附件。
拖動部分
新建類ShapeManagement 由它來管理縮放與移動。
class ShapeManagement { private Shape previseSelectedShape; private Brush previseSelectedShapeBrush; //使被選中的圖形呈現橘黃色 private Brush selectedBrush = Brushes.Orange; public void SelectedChange(Shape shape) { ClearSelectedEffect(); previseSelectedShape = shape; previseSelectedShapeBrush = previseSelectedShape.Fill.Clone(); previseSelectedShape.Fill = selectedBrush; } public void ClearSelectedEffect() { if (previseSelectedShape != null) previseSelectedShape.Fill = previseSelectedShapeBrush; } }
在ViewModel創建一個圖形管理器:
private ShapeManagement shapeManagement = new ShapeManagement();
在MouseDown中加入如下代碼:
if(MovingModeEnable) { if (e.Source is Shape) shapeManagement.SelectedChange(e.Source as Shape); else if(e.Source is Panel) shapeManagement.ClearSelectedEffect(); }
之后就是移動的部分,在ShapeManagement加入如下代碼:
class ShapeItem { public Shape DisplayShape { get; set; } public TranslateTransform translateTransform { get; set; } public Point PositonRecord { get; set; } public Point HistoryPositonRecord { get; set; } } private List<ShapeItem> shapeList = new List<ShapeItem>(); public void Add(Shape shape) { var shapeItem = new ShapeItem() { DisplayShape = shape, translateTransform = new TranslateTransform(), PositonRecord = new Point(), HistoryPositonRecord = new Point() }; shapeList.Add(shapeItem); shape.RenderTransform = new TransformGroup() { Children = new TransformCollection() { shapeItem.translateTransform } }; }
之前,我們已經拿到了當前選中的對象,然后就可以根據LINQ查詢,來操作該對象,找到相應的變形,點的信息,予以操作。
代碼在附件中,目前還有一些BUG。
開發環境VS2013, .NET4.5。