【发布时间】:2014-10-09 06:55:44
【问题描述】:
我想澄清一些关于违反 MVVM 的问题。因此,我创建了一个解决方案,其中包含一些项目来演示这些案例。 这是解决方案的定义(项目):
- 视图(它是一个 WPF 类库,显然它有视图)
- ViewModel(它是一个类库,显然它有视图模型)
- 模型(它是一个类库,显然它有模型)
- 域(它是一个 Class Libraray 并且它具有应用程序 dataModels)
- 核心(它是一个类库,它具有 wpf 的核心,如 RelayCommnd 或 EventToCommand)
- 应用程序(它是一个 wpf 应用程序和启动项目)
- ExternalCustomControl(它是一个虚构的第三方公司创建的 wpf 自定义控件库)
我为您提供下载整个解决方案以便更好地理解 Here
第一期: 我在 MainWindow.xaml 中有一个 EventToCommand 用于窗口的 Closing 事件,并将其附加到 MainWindowClosingCommand PassEventArgsToCommand 设置为 True,然后,在 MainViewModel 中有一个名为 OnMainWindowClosing
的命令的处理程序private void OnMainWindowClosing(object parameter)
{
var arg = parameter as CancelEventArgs;
// What is the best way to show message dialog to user?
// Do i have to send message to the View to show the messageBox dialog and then the window send me the answer back to continue?
// What about IMessageBoxService? Doesn't it violates MVVM?
// Doesn't following code violates the MVVM?
// Cancel the Closing of a Window isnt a UI side duty?
arg.Cancel = true;
}
并且完全每当您想设置 e.Handled 或 e.Cancel 时都会遇到此问题。那么您知道不需要投射的任何其他方式吗参数为 CancelEventArgs ?
第二期: 我在 MainWindow.xaml 中有一个 EventToCommand 用于网格的 PreviewMouseDown 事件,并将其附加到 MouseClickCommand PassEventArgsToCommand 设置为 True,然后,在 MainViewModel 中有一个名为 OnMouseClick 的命令的处理程序:
private void OnMouseClick(object parameter)
{
// var arg = parameter as MouseButtonEventArgs;
// This is the violation of MVVM : To cast the parameter to MouseButtonEventArgs i have to add a refrence
// to PresentationCore.dll in the ViewModel Project
// The next and worse step is that in most cases we need to know the Original Source of the event
// (maybe its a StackPanel or a Label or etc) and this again vioaltes the MVVM
// So Whats the WorkAround?
}
第三期: 我在我的 MainWindow 中使用了第三方控件(Imagine Infragistics 或 DevExpress 或任何其他第三方控件,但这里作为示例,我在我的解决方案中创建了虚构控件作为 ExternalCustomControl 项目)像这样:
<thirdParty:ThirdPartyCustomControl Grid.Row="1"
ItemsSource="{Binding MyItemsSource,Converter={StaticResource converterKey}}" />
和 ThirdPartyCustomControl 具有 IEnumarabe<CustomControlDataModel> 类型的属性(CustomControlDataModel 是存在于 ExternalCustomControl 程序集中的类型)但是您知道是否要在 MainViewModel 中创建属性 strong> 对于 CustomControlDataModel 类型的控件,您必须在 ViewModel 项目中添加对 ExternalCustomControl.dll 的引用,这违反了 MVVM,因此我创建了一个名为 MyDataModel 的类型 并将控件的 ItemsSource 绑定到 MainViewModel 中的 MyItemsSource 属性:
// If i define MyItemsSource as List<CustomControlDataModel> i have to add a refrence to ExternalCustomControl.dll
// and i think its again violate the MVVM (because ExternalCustomControl.dll is a UI Side Controls Assembly)
public List<MyDataModel> MyItemsSource { get; set; }
所以我将 CustomControlDataModel 类型的属性绑定到 MyDataModel 类型的属性,当然我需要一个转换器:
public object Convert(object value, Type targetType, object parameter, c System.Globalization.CultureInfo culture)
{
// Imagine when the source data (MyDataModel) is huge (for example 1 milion) it (this dummy Conversion)
// affects the performance
if (value is List<MyDataModel>)
{
var result = new List<CustomControlDataModel>();
(value as List<MyDataModel>).ForEach(myVal =>
{
var custDataModel = new CustomControlDataModel();
custDataModel.ID = myVal.ID;
custDataModel.Name = myVal.Name;
custDataModel.Age = myVal.Age;
result.Add(custDataModel);
});
return result;
}
return value;
}
问题是您是否知道比这种虚拟转换更好的方法,或者您通常将第三方程序集添加到您的视图和视图模型中?
这些是我遇到的问题,如果您知道其他问题并与大家分享您的专业知识,如果您添加更多内容,我将不胜感激。
更新:
对于第一期的MessageBox部分,我建议使用此链接 MesageBox
谢谢。
【问题讨论】:
-
UserControls should NOT have view models. 这是一种代码气味。你可以说出来,因为你在做这件事时遇到了问题。您还将 UI 问题推到了视图模型中。 UI 问题在 代码隐藏 中。 MVVM != 没有代码隐藏。
-
@会不会是这个问题
标签: c# wpf design-patterns mvvm