真正的MVVM和第三方控件

Pra*_*eep 5 c# wpf infragistics mvvm xamdatagrid

在True MVVM模型中,我们不希望xaml.cs中有任何代码,我们也不希望viewModel具有视图引用.但是,所有第三方控件都不能为True MVVM提供良好的支持.

在我的情况下,我使用Infragistics xamDatagrid控件,我想将其数据导出到Excel.我可以将数据导出到数据网格的唯一方法是使用以下代码:

xamDataGridExcelExporter.xamDataGridExcelExporter xamDataGridExcelExporter1 =       
   new xamDataGridExcelExporter.xamDataGridExcelExporter();   
xamDataGridExcelExporter1.Export(**this.xamDataGrid1**,   
   @"C:\Excel\ExportFile.xls");
Run Code Online (Sandbox Code Playgroud)

但是,XamDataGridExcelExporter将输入作为this.xamDataGrid.xamDataGrid是View not viewModel的一部分. 那么我们如何才能处理我们需要viewModel中的视图实例的情况.

Ric*_*key 10

MVVM禁止代码隐藏是一种常见的误解.事实上,代码隐藏不可重用,而且与视图密不可分,因此如果没有自动化,它就无法进行单元测试.但它确实有它的用途.

什么本质上不好有关代码隐藏.实际上,它您编写的支持视图的所有其他代码(如转换器,自定义控件等)没有太大区别.这些代码都不能通过视图模型单元测试进行测试.代码隐藏的唯一区别是它不太可重用.但它仍然是你观点一部分,观点也不错.

通常,缺少代码隐藏是视图和视图模型之间清晰分离的良好指示.然而,在其他干净的设计中存在一些代码隐藏通常仅表示对标准控件和数据绑定和命令很难做的事情.

在您的情况下,导出XamDataGrid 绝对是视图特定的.它必须与您为视图选择的第三方库完全相同.因此,它非常有意义,它不应该是视图模型的一部分.

如果你仍然没有设置任何代码隐藏,你可以使用行为,如ACB混合行为来编写你原本会放入代码隐藏的功能.只是意识到即使是行为仍然是视图的一部分,只有更多可重用的代码隐藏.


Luc*_*Bos 3

您可以围绕 xamDataGrid 编写一个包装器,该包装器具有名为 filename 的依赖属性。然后视图模型可以绑定到该属性。当 xamDataGrid 检测到文件名属性发生更改时,它可以执行您建议的代码。然后重置文件名属性以获取进一步通知。

此解决方案将代码从您的后台代码中排除,并让 xamDataGrid 负责导出其数据。

- - - -编辑 - - - - -

第二种解决方案可以利用 MVVM light Messenger 类。让您的包装器监听消息,而不是声明依赖属性。当视图模型发送消息(例如可以将文件名作为参数)时,包装器可以执行代码。

例如

public class ExportableXamDataGrid: XamDataGrid
{
    public ExportableXamDataGrid():base()
    {
        Messenger.Default.Register<string>(this,"ExportExcel",ExportFile);
    }

    private void ExportFile(string file)
    {
        xamDataGridExcelExporter.xamDataGridExcelExporter xamDataGridExcelExporter1 =       
        new xamDataGridExcelExporter.xamDataGridExcelExporter();   
        xamDataGridExcelExporter1.Export(**this.xamDataGrid1**,   
           @"C:\Excel\ExportFile.xls");

    }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的视图模型中你可以这样做:

 Messenger.Default.Send(@"C:\Excel\ExportFile.xls","ExportExcel");
Run Code Online (Sandbox Code Playgroud)

您的问题有很多解决方案,所有这些解决方案您都不必开始编写您认为的逻辑。

http://www.lucbos.net/2011/06/using-codebehind-in-mvvm.html

  • 谢谢@Luc Bos。这是一个干净的解决方案,不仅在这种情况下有用,而且在第三方控件不兼容 MVVM 的情况下也有用。 (2认同)