当使用MVVM模式时,我应该在哪里放置与视图强连接但尺寸巨大的方法?
本文关键字:连接 视图 方法 巨大 模式 MVVM 在哪里 我应该 | 更新日期: 2023-09-27 18:18:15
继续我之前关于viewmodel混乱状态的问题,我如何避免viewmodel中的命令混乱?我有一个新问题。对于一个学校项目,我正在使用MVVM模式在WPF中制作一个图像编辑桌面应用程序。由于所有的编辑选项(裁剪调整大小等),有相当多的命令,调用代码繁重的方法,使用GDI+属性和方法,以及事件。现在视图模型有770行,这让我想哭。像这两种方法(哦,天哪,请记住我是四个月前开始编程的)应该去哪里?
private void ToGrayscale()
{
Bitmap template = CurrentImage.LoadedImage.ToBitmap();
var drawing = new Bitmap(template.Width, template.Height);
var drawingsurface = Graphics.FromImage(drawing);
var attributes = new ImageAttributes();
attributes.SetColorMatrix(ImageFilters.GrayScaleMatrix);
drawingsurface.DrawImage(template, new System.Drawing.Rectangle(0, 0, template.Width, template.Height),
0, 0, template.Width, template.Height, GraphicsUnit.Pixel, attributes);
drawingsurface.Dispose();
AddSnapshot(drawing, "Desaturate");
CurrentImage.LoadedImage = drawing.ToBitmapImage();
UiImageContainer.Source = CurrentImage.LoadedImage;
}
private void OnMouseMove(object sender, MouseEventArgs args)
{
if (UiImageContainer.IsMouseCaptured && args.GetPosition(UiImageContainer).X > 0 &&
args.GetPosition(UiImageContainer).Y < UiImageContainer.Source.Height && args.GetPosition(UiImageContainer).Y > 0 &&
args.GetPosition(UiImageContainer).X < UiImageContainer.Source.Width)
{
if (_rubberBand == null)
{
_rubberBand = new System.Windows.Shapes.Rectangle();
_rubberBand.VerticalAlignment = VerticalAlignment.Top;
_rubberBand.HorizontalAlignment = HorizontalAlignment.Left;
var partiallyTransparentSolidColorBrush = new SolidColorBrush(Colors.White);
partiallyTransparentSolidColorBrush.Opacity = 0.25;
_rubberBand.Fill = partiallyTransparentSolidColorBrush;
_rubberBand.Stroke = new SolidColorBrush(Colors.LightGray);
ContentGrid.Children.Add(_rubberBand);
}
var width = Math.Abs(_mouseLeftDownPoint.X - CurrentImagePoint.X);
var height = Math.Abs(_mouseLeftDownPoint.Y - CurrentImagePoint.Y);
var left = Math.Min(_mouseLeftDownPoint.X, CurrentImagePoint.X);
var top = Math.Min(_mouseLeftDownPoint.Y, CurrentImagePoint.Y);
_rubberBand.Width = width;
_rubberBand.Height = height;
var size = new Thickness(left, top, 0, 0);
_rubberBand.Margin = size;
}
}
例如,您可以这样做
// your original ToGreyscale modified
private void ToGrayscale()
{
Bitmap greyscaleImage = ConvertToGreyscale(CurrentImage.LoadedImage.ToBitmap());
AddSnapshot(greyscaleImage, "Desaturate");
CurrentImage.LoadedImage = greyscaleImage .ToBitmapImage();
UiImageContainer.Source = CurrentImage.LoadedImage;
}
// put this in another class
private Bitmap ConvertToGrayscale(Bitmap originalImage)
{
var drawing = new Bitmap(originalImage.Width, originalImage.Height);
var drawingsurface = Graphics.FromImage(drawing);
var attributes = new ImageAttributes();
attributes.SetColorMatrix(ImageFilters.GrayScaleMatrix);
drawingsurface.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, originalImage.Width, originalImage.Height),
0, 0, template.Width, template.Height, GraphicsUnit.Pixel, attributes);
drawingsurface.Dispose();
return drawing
}
一个更"性感"的方法是让ConvertToGreyscale成为Bitmap的扩展方法。
你的_rubberBand最终应该是一个类,RubberBand可能,
then do _rubberBand.HandleMouseMove(…);
基本上,将东西移动到不耦合到视图模型的单独方法中,然后考虑将这些方法移动到其他类中。这个过程会让你思考你需要如何构建事物。你会发现当你需要把东西移到其他类时,那些类需要与你的视图模型/UI交互。你会想,‘嗯,我不想让它们直接引用我的UI/VM等’,然后你开始想,好吧,也许我需要想出一些接口,我的类可以通过.....工作然后让我的VM/UI实现这些接口。
例如,你可能会发现OnMouseMove,发生的事情取决于Context然后你有一个RubberBandSelection Context或类似的东西。然后你想出一种通用的方式来拥有不同的上下文当你有复杂的行为时,考虑如何将其分解成更小的部分(单独的类)。
想象一座摩天大楼。它是一个巨大的物体吗?或者它是一个小部分的集合,每个小部分都有不同的工作(柱子、大梁、窗户等)?也许梁是由用螺栓连接的梁组成的。任何系统都可以分解成更小的组件,直到每个组件完成一个明确定义的任务。
就视图类而言,尝试将UI与它所做的工作分开-例如,ToGreyscale是可以包含在类中的"图像处理功能"的一个很好的例子。其他图像处理函数可以写入类似的类中,它们都派生自相同的基类或接口,因此它们成为可互换的组件。
通过这种方式组织你的代码,你可以用许多小的、简单的组件制作一个非常复杂的应用程序,并且很容易添加新的组件来扩展程序超出其原始设计。
创建一个单独的类库(dll),它将由您的VM使用的不同服务代理使用,并将所有不是VM直接负责的代码移到那里。
为了避免紧耦合,请确保使用服务代理,并且这些服务代理实现可应用的接口,而不是直接引用这些新对象,这样你的应用程序就不必引用这个类库。
使用面向对象的设计模式和面向对象设计的三大支柱(封装、继承和多态性)来适当地组织类库中的代码,并为这些对象实现DRY(不要重复自己)状态。
继续用用户名/图片问更详细的问题,这将确保你很快得到很多好的答案…