2011-12-18 63 views
8

我正在构建一个使用相当多的命令的应用程序,并且它们混乱了我的视图模型。 MVVM对我来说是新手,所以如果这个问题有点愚蠢,那么很抱歉。有没有办法减少混乱?例如在这里你可以看到杂乱的一部分..如何避免ViewModel中的命令混乱?

private void InitializeCommands() 
    { 
     LogoutCommand = new RelayCommand(Logout); 
     OpenCommand = new RelayCommand(SetImage); 
     SaveCommand = new RelayCommand(SaveImage, SaveImageCanExecute); 
     UploadToFlickrCommand = new RelayCommand(UploadToFlickr); 
     CropCommand = new RelayCommand(SetCropMouseEvents); 
     RemoveRedEyeCommand = new RelayCommand(SetRemoveRedEyeMouseEvents); 
     TextInputCropCommand = new RelayCommand(CropFromText); 
     ReloadImageCommand = new RelayCommand(ReloadImage); 
     FlipYCommand = new RelayCommand(FlipY); 
     Rotate90RCommand = new RelayCommand(Rotate90R); 
     FlipXCommand = new RelayCommand(FlipX); 
     ToGrayscaleCommand = new RelayCommand(ToGrayscale); 
     ToSepiaCommand = new RelayCommand(ToSepia); 
     WindowClosingCommand = new RelayCommand(WindowClosing); 
     EffectsViewCommand = new RelayCommand(() => CurrentToolView = new EffectsView()); 
     AddTextCommand = new RelayCommand(() => CurrentToolView = new AddTextView()); 
     ResizeCommand = new RelayCommand(() => CurrentToolView = new ResizeView()); 
     CropViewCommand = new RelayCommand(() => CurrentToolView = new CropView()); 
     RedEyeCommand = new RelayCommand(() => CurrentToolView = new RedEyeView()); 
     RotateViewCommand = new RelayCommand(() => CurrentToolView = new RotateView()); 
     ExitCommand = new RelayCommand(() => Application.Current.Shutdown()); 
     FullscreenCommand = new RelayCommand(() => 
               { 
                var fs = new FullscreenView 
                    {FullscreenImage = CurrentImage.LoadedImage}; 
                fs.Show(); 
               }); 
     HandleDropCommand = new RelayCommand<DragEventArgs>(e => OnFileDrop(this, e)); 
     Messenger.Default.Register<User>(this, "UserLogin", SetUser); 
     Messenger.Default.Register<FlickrAccount>(this, "AddedAccount", AddAccount); 
     Messenger.Default.Register<string>(this, "INeedAUser", SendUser); 
     Messenger.Default.Register<string>(this, "INeedAImage", SendImage); 
    } 
+0

我也有兴趣看到一个很好的答案,但AFAIK这是所有的松耦合善良支付的代价。 – Jon 2011-12-18 15:08:48

回答

5

让你有命令:

  1. 文件操作(打开,保存,上传到闪烁)

  2. 窗口操作(全屏,关闭)

  3. 编辑(旋转,颜色等)

考虑分组(com摆出)相关命令一起在一个自定义类中调用,例如FileCommands。如果适用,创建多级分层结构。如果您的视图中有层次菜单,您可能需要类似的命令层次结构。

然后,为每个命令组(例如FileController)创建一个控制器,并在控制器创建方法中将FileCommands组中的命令与相关服务一起注册。

请参阅http://waf.codeplex.com/示例应用程序(例如BookController.cs)了解如何实际实现Controller/ViewModel映射的一些想法。但请注意,它并不完全相同(不会将命令分为组)。

+0

非常有趣,我喜欢这个主意。看起来有点复杂(对我来说,作为一个新手),但我会看看它,让你知道我是怎么去的!感谢您的回答:) – 2011-12-18 16:23:41

+0

如果您不想要控制器,那么只需按照建议对相关命令进行分组,然后将InitializeCommands方法分为InitializeFileCommands,InitializeWindowCommands等。 – surfen 2011-12-18 16:40:10

0

您的视图模型是意味着是视图和模型之间的胶水。这意味着,除非您可以一般地重复模型,否则它将总是包含“胶水线”的枚举。

我可以想象你可以摆脱的唯一混乱是你不需要字面上的XXXCommand属性;在这种情况下,您可以创建财产状,结构像(伪代码)

private void createCommands() { 
    var commands={ 
     "Logout"=>new RelayCommand(Logout), 
     "Exit"=>new RelayComand(()=>Application.Current.Shutdown()), 
    .... 
    }; 
    foreach(var key,cmd in commands){ 
     glue(key,cmd); 
    } 
}; 

没有其他的理由让你在这里创建,除了它们胶粘到正确的视图中的对象引用的集合粘合剂。

但是再次,为什么不使用属性成语呢?再说一遍:正如我所见,杂乱无章的数量是有限的。

+0

谢谢你的回答,我会再次查看代码并明天问我的老师。我稍后会重新发布代码,您可以看到结果:) – 2011-12-18 15:30:43

+0

只需要注意一点:在字符串中使用名称会使编译器不可见(即无法检查一致性)。另一方面;它也无法检查一个属性是否被使用或不... – FrankB 2012-09-24 10:28:34

1

使用Caliburn Micro。对于名为name =“Logout”的按钮,ViewModel中唯一需要的是名为Logout的公共方法。

而且没有convetion绑定:

<Button Content="Remove" 
     cal:Message.Attach="[Event Click] = [Action Remove($dataContext)]" /> 

然后在视图模型添加一个方法命名删除和样品中的DataContext传递给方法。

+0

什么是Caliburn Micro,它开始使用起来有多容易它?我们目前使用MVVM灯,它们可以一起使用吗?感谢您的回应:) – 2011-12-18 16:22:43

+0

CM是一个基于WPF和SL的基于约定的MvvM框架。 http://caliburnmicro.codeplex.com/。入门并不糟糕,但我不认为你会同时使用两者。 – 2011-12-18 16:35:18