WPF learning 12: Drawing and editing tools based on MVVM Light (3), wpfmvvm
This article is about how to create a graphic editing tool based on MVVM Light (2 ).
This time the goal is to complete
Two tasks.
Effect after completion of this section:
This article consists of three parts:
1. Redesign where the previous code is unreasonable.
2. You can select the color of the outer frame for the image.
3. Introduction to the implementation of drag graphics.
Code before modification
When we write code, we often look back at the previous Code. If we think there is a problem with the previous Code, if the conditions are allowed, we should change it.
Changes made:
1. Change Image to Canvas.
Objective: To greatly simplify the code of zooming and moving the image.
Remove the configuration button. The reason is: because the Image is replaced with a Canvas, the cost of changing the Canvas size is reduced to nearly 0, and the width and height of the Canvas can be directly bound. ,
The code will not be pasted. The attachment contains the engineering source code.
Color part
Effect:
Process: bind the List and attributes related to colors. In the front-end code, we need to write a template and bind it:
<TextBlock VerticalAlignment = "Center"> <Run Text = "outer box color: "/> </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 = "fill color: "/> </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>
Next, we need to implement a list and two color attributes in ViewModel. Note: The element bound to ItemSource must bePublic attribute, cannot be a field!
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];}
In this step, data binding is complete.
Through BackGroundColor and BorderColor, we can get the selected colors. In the background code, we can use them when drawing. The code is located in the attachment.
Drag part
You can create a class ShapeManagement to manage scaling and movement.
Class ShapeManagement {private Shape previseSelectedShape; private Brush previseSelectedShapeBrush; // render the selected image orange private Brush selectedBrush = Brushes. orange; public void SelectedChange (Shape shape) {ClearSelectedEffect (); previseSelectedShape = shape; previseSelectedShapeBrush = previseSelectedShape. fill. clone (); previseSelectedShape. fill = selectedBrush;} public void ClearSelectedEffect () {I F (previseSelectedShape! = Null) previseSelectedShape. Fill = previseSelectedShapeBrush ;}}
Create a graphical manager in ViewModel:
private ShapeManagement shapeManagement = new ShapeManagement();
Add the following code to MouseDown:
if(MovingModeEnable){ if (e.Source is Shape) shapeManagement.SelectedChange(e.Source as Shape); else if(e.Source is Panel) shapeManagement.ClearSelectedEffect();}
Now we can get the clicked object
The following is the moving part. Add the following code to the 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 } };}
Previously, we have obtained the currently selected object, and then we can perform operations on this object based on the LINQ query, find the corresponding deformation and vertex information, and perform operations.
The code is included in the attachment, and there are still some bugs.
Development Environment VS2013,. NET4.5.
Source code