当使用MVVM模式时,我应该在哪里放置与视图强连接但尺寸巨大的方法?



继续我之前关于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(不要重复自己)状态。

继续用用户名/图片问更详细的问题,这将确保你很快得到很多好的答案…

最新更新