C#WPF屏幕截图应用程序--通过鼠标事件处理画布上的绘图
我正在用WPF制作一个截图程序。我不明白的是我应该如何使用鼠标点击事件。我的所有鼠标事件都是在代码隐藏中处理的,这非常有效,但我想将我的项目转换为MVVM风格。下面是我所有的ScreenshotTab代码,它是承载屏幕截图的usercontrol(它实际上被设计为放置在tabcontrol选项卡项中):C#WPF屏幕截图应用程序--通过鼠标事件处理画布上的绘图,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在用WPF制作一个截图程序。我不明白的是我应该如何使用鼠标点击事件。我的所有鼠标事件都是在代码隐藏中处理的,这非常有效,但我想将我的项目转换为MVVM风格。下面是我所有的ScreenshotTab代码,它是承载屏幕截图的usercontrol(它实际上被设计为放置在tabcontrol选项卡项中): 公共部分类屏幕快照选项卡:用户控件 { 公共屏幕快照选项卡() { 初始化组件(); } 公共屏幕快照选项卡(位图图像屏幕快照,窗口) { 初始化组件(); imgControl.Source=
公共部分类屏幕快照选项卡:用户控件
{
公共屏幕快照选项卡()
{
初始化组件();
}
公共屏幕快照选项卡(位图图像屏幕快照,窗口)
{
初始化组件();
imgControl.Source=屏幕截图;
imgControl.MaxWidth=屏幕截图.Width;
imgControl.MaxHeight=屏幕截图.Height;
canvas.Height=screenshot.Height;
canvas.MinHeight=屏幕截图.Height;
canvas.MaxHeight=屏幕截图.Height;
canvas.Width=screenshot.Width;
canvas.MinWidth=屏幕截图.Width;
canvas.MaxWidth=屏幕截图.Width;
mainWindow=作为主窗口的窗口;
}
公共场所被保留
{
得到;
设置
}
公共位图图像截图
{
得到
{
if(imgControl.Source为位图图像)
{
将imgControl.Source作为BitmapImage返回;
}
其他的
{
返回null;
}
}
}
//在事件处理程序内部的逻辑流中按需要的顺序列出。
私有主窗口主窗口;
私人椭圆圈;
私有多段线;
专用点起始点;
专用点端点;
专线;
私有矩形;
私人点左上角;
//我可能不需要一本书。
私有布尔图;
私有无效imgControl_MouseDown(对象发送器,MouseButtonEventArgs e)
{
//Show(“鼠标按下事件正在工作…”);
//MessageBox.Show(“mainwindow.toolselected=“+mainwindow.toolselected.ToString());
//设置直线的起点,该起点不变
//当用户移动鼠标时。
//启用表示启用时正在绘制的标志。
isDrawing=true;
开关(主窗口。选择工具)
{
case DrawingTool.FreeDraw:
多段线=新的多段线();
设置行程特性(多段线);
polyLine.Points.Add(例如GetPosition(canvas));
canvas.Children.Add(多段线);
打破
案例绘图工具线:
行=新行();
设定行程特性(直线);
line.X1=e.GetPosition(画布).X;
line.Y1=e.GetPosition(画布).Y;
line.X2=e.GetPosition(画布).X;
line.Y2=e.GetPosition(画布).Y;
canvas.Children.Add(行);
打破
案例绘图工具矩形:
矩形=新矩形();
设置行程属性(矩形);
startPoint=e.GetPosition(此);
端点=e.GetPosition(此);
SetLeft(矩形,startPoint.X);
SetTop(矩形,startPoint.X);
canvas.Children.Add(矩形);
打破
案例绘图工具圆:
圆=新椭圆();
设定行程特性(圆形);
startPoint=e.GetPosition(此);
端点=e.GetPosition(此);
Canvas.SetLeft(圆形,startPoint.X);
Canvas.SetTop(圆形,startPoint.X);
canvas.Children.Add(圆圈);
打破
机箱绘图工具橡皮擦:
打破
违约:
打破
}
}
私有void SetStrokeProperties(形状)
{
shape.Stroke=新的SolidColorBrush(mainWindow.color);
shape.StrokeThickness=3;
}
//这是我们的橡皮擦活动。
//选择工具时,它只是从对象中删除元素
//是橡皮擦工具,我们把鼠标放下了。
MouseOver上的私有void(对象发送方,MouseEventArgs e)
{
//MessageBox.Show(“耶,鼠标悬停在名为…”的事件上);
if(isDrawing&(mainWindow.toolSelected==DrawingTool.橡皮擦))
{
canvas.Children.Remove(发送方作为UIElement);
}
}
私有无效imgControl\u MouseMove(对象发送方,MouseEventArgs e)
{
if(isDrawing)
{
开关(主窗口。选择工具)
{
case DrawingTool.FreeDraw:
polyLine.Points.Add(例如GetPosition(canvas));
打破
案例绘图工具线:
line.X2=e.GetPosition(画布).X;
line.Y2=e.GetPosition(画布).Y;
打破
案例绘图工具矩形:
端点=e.GetPosition(此);
矩形.Width=Math.Abs(endPoint.X-startPoint.X);
rectangle.Height=Math.Abs(endPoint.Y-startPoint.Y);
//向下向右。
if((endPoint.X>=startPoint.X)和&(endPoint.Y>=startPoint.Y))
{
//在这种情况下,起点是矩形的左上角点。
左上角.X=起始点.X;
左上角.Y=起始点.Y;
SetLeft(矩形,左上角.X);
画布.SetTop(矩形,左上角.Y);
}
//向上向右。
如果((endPoint.X>=startPoint.X)&&&(endPoint.Y=startPoint.X)&&(endPoint.Y我用一个c
public partial class ScreenshotTab : UserControl
{
public ScreenshotTab()
{
InitializeComponent();
}
public ScreenshotTab(BitmapImage screenshot, Window window)
{
InitializeComponent();
imgControl.Source = screenshot;
imgControl.MaxWidth = screenshot.Width;
imgControl.MaxHeight = screenshot.Height;
canvas.Height = screenshot.Height;
canvas.MinHeight = screenshot.Height;
canvas.MaxHeight = screenshot.Height;
canvas.Width = screenshot.Width;
canvas.MinWidth = screenshot.Width;
canvas.MaxWidth = screenshot.Width;
mainWindow = window as MainWindow;
}
public bool isSaved
{
get;
set;
}
public BitmapImage Screenshot
{
get
{
if (imgControl.Source is BitmapImage)
{
return imgControl.Source as BitmapImage;
}
else
{
return null;
}
}
}
// Listed in the order they are needed in the logic flow inside the event handlers.
private MainWindow mainWindow;
private Ellipse circle;
private Polyline polyLine;
private Point startPoint;
private Point endPoint;
private Line line;
private Rectangle rectangle;
private Point topLeft;
// I probably don't need a bool.
private bool isDrawing;
private void imgControl_MouseDown(object sender, MouseButtonEventArgs e)
{
// MessageBox.Show("Mouse down event is working...");
// MessageBox.Show("mainwindow.toolselected = " + mainWindow.toolSelected.ToString());
// Sets the starting point of the line, which doesn't change
// as the user moves their mouse.
// Turns on a flag that represents that we are drawing when on.
isDrawing = true;
switch (mainWindow.toolSelected)
{
case DrawingTool.FreeDraw:
polyLine = new Polyline();
SetStrokeProperties(polyLine);
polyLine.Points.Add(e.GetPosition(canvas));
canvas.Children.Add(polyLine);
break;
case DrawingTool.Line:
line = new Line();
SetStrokeProperties(line);
line.X1 = e.GetPosition(canvas).X;
line.Y1 = e.GetPosition(canvas).Y;
line.X2 = e.GetPosition(canvas).X;
line.Y2 = e.GetPosition(canvas).Y;
canvas.Children.Add(line);
break;
case DrawingTool.Rectangle:
rectangle = new Rectangle();
SetStrokeProperties(rectangle);
startPoint = e.GetPosition(this);
endPoint = e.GetPosition(this);
Canvas.SetLeft(rectangle, startPoint.X);
Canvas.SetTop(rectangle, startPoint.X);
canvas.Children.Add(rectangle);
break;
case DrawingTool.Circle:
circle = new Ellipse();
SetStrokeProperties(circle);
startPoint = e.GetPosition(this);
endPoint = e.GetPosition(this);
Canvas.SetLeft(circle, startPoint.X);
Canvas.SetTop(circle, startPoint.X);
canvas.Children.Add(circle);
break;
case DrawingTool.Eraser:
break;
default:
break;
}
}
private void SetStrokeProperties(Shape shape)
{
shape.Stroke = new SolidColorBrush(mainWindow.color);
shape.StrokeThickness = 3;
}
// This is our eraser event.
// It simply removes the element from the object when the tool selected
// is the eraser tool and we have the mouse down.
private void OnMouseOver(object sender, MouseEventArgs e)
{
// MessageBox.Show("Yay, mouse over event called...");
if (isDrawing && (mainWindow.toolSelected == DrawingTool.Eraser))
{
canvas.Children.Remove(sender as UIElement);
}
}
private void imgControl_MouseMove(object sender, MouseEventArgs e)
{
if (isDrawing)
{
switch (mainWindow.toolSelected)
{
case DrawingTool.FreeDraw:
polyLine.Points.Add(e.GetPosition(canvas));
break;
case DrawingTool.Line:
line.X2 = e.GetPosition(canvas).X;
line.Y2 = e.GetPosition(canvas).Y;
break;
case DrawingTool.Rectangle:
endPoint = e.GetPosition(this);
rectangle.Width = Math.Abs(endPoint.X - startPoint.X);
rectangle.Height = Math.Abs(endPoint.Y - startPoint.Y);
// down and to the right.
if ((endPoint.X >= startPoint.X) && (endPoint.Y >= startPoint.Y))
{
// In this case, the start point is the top left point of the rectangle.
topLeft.X = startPoint.X;
topLeft.Y = startPoint.Y;
Canvas.SetLeft(rectangle, topLeft.X);
Canvas.SetTop(rectangle, topLeft.Y);
}
// up and to the right.
else if ((endPoint.X >= startPoint.X) && (endPoint.Y <= startPoint.Y))
{
topLeft.X = endPoint.X - rectangle.Width;
topLeft.Y = endPoint.Y;
Canvas.SetLeft(rectangle, topLeft.X);
Canvas.SetTop(rectangle, topLeft.Y);
}
// up and to the left...
else if ((endPoint.X <= startPoint.X) && (endPoint.Y <= startPoint.Y))
{
topLeft.X = endPoint.X;
topLeft.Y = endPoint.Y;
Canvas.SetLeft(rectangle, topLeft.X);
Canvas.SetTop(rectangle, topLeft.Y);
}
// down to the left...
else if ((endPoint.X <= startPoint.X) && (endPoint.Y >= startPoint.Y))
{
topLeft.X = startPoint.X - rectangle.Width;
topLeft.Y = endPoint.Y - rectangle.Height;
Canvas.SetLeft(rectangle, topLeft.X);
Canvas.SetTop(rectangle, topLeft.Y);
}
break;
case DrawingTool.Circle:
endPoint = e.GetPosition(this);
circle.Width = Math.Abs(endPoint.X - startPoint.X);
circle.Height = Math.Abs(endPoint.Y - startPoint.Y);
// down and to the right.
if ((endPoint.X >= startPoint.X) && (endPoint.Y >= startPoint.Y))
{
// In this case, the start point is the top left point of the rectangle.
topLeft.X = startPoint.X;
topLeft.Y = startPoint.Y;
Canvas.SetLeft(circle, topLeft.X);
Canvas.SetTop(circle, topLeft.Y);
}
// up and to the right.
else if ((endPoint.X >= startPoint.X) && (endPoint.Y <= startPoint.Y))
{
topLeft.X = endPoint.X - circle.Width;
topLeft.Y = endPoint.Y;
Canvas.SetLeft(circle, topLeft.X);
Canvas.SetTop(circle, topLeft.Y);
}
// up and to the left...
else if ((endPoint.X <= startPoint.X) && (endPoint.Y <= startPoint.Y))
{
topLeft.X = endPoint.X;
topLeft.Y = endPoint.Y;
Canvas.SetLeft(circle, topLeft.X);
Canvas.SetTop(circle, topLeft.Y);
}
// down to the left...
else if ((endPoint.X <= startPoint.X) && (endPoint.Y >= startPoint.Y))
{
topLeft.X = startPoint.X - circle.Width;
topLeft.Y = endPoint.Y - circle.Height;
Canvas.SetLeft(circle, topLeft.X);
Canvas.SetTop(circle, topLeft.Y);
}
break;
default:
break;
}
}
}
private void imgControl_MouseUp(object sender, MouseButtonEventArgs e)
{
isSaved = false;
switch (mainWindow.toolSelected)
{
case (DrawingTool.FreeDraw):
polyLine.MouseEnter += OnMouseOver;
break;
case (DrawingTool.Line):
line.MouseEnter += OnMouseOver;
break;
case (DrawingTool.Rectangle):
rectangle.MouseEnter += OnMouseOver;
break;
case (DrawingTool.Circle):
circle.MouseEnter += OnMouseOver;
break;
}
isDrawing = false;
// MessageBox.Show("Mouse up event fired...");
}
}
public interface IMouseArgs
{
Point Pos { get; }
void Capture();
void Release();
bool Handled { get; set; }
... lots of other stuff
}
<SomeControl>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<cmd:EventToCommand Command="{Binding MouseDownCommand}"
PassEventArgsToCommand="True"
EventArgsConverter="{StaticResource ClickConverter}"
EventArgsConverterParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:SomeParentWindow}}"/>
</i:EventTrigger>