简体   繁体   English

MVVM如何为Datagrid设计ViewModel,用户选择哪些列

[英]MVVM How to Design a ViewModel for a Datagrid which columns are chosen by user

So when i have a Datagrid which i want to fill with data from my Database. 所以当我有一个Datagrid,我想填充我的数据库中的数据。 I normally design a ViewModel with the Data i wanted to display. 我通常使用我想要显示的Data设计一个ViewModel。 But how do i create an ViewModel for my Datagrid when i dont know before which data it will display in it ? 但是,当我不知道它将显示在哪个数据之前,我如何为我的Datagrid创建一个ViewModel?

So when i allow the user of my application to specify the Columns from the database table which he wants to display in the Datagrid. 因此,当我允许应用程序的用户从数据库表中指定要在Datagrid中显示的列时。 How do i design the ViewModel for that case ? 我如何为这种情况设计ViewModel?

So i hope its clear what i want to do. 所以我希望它清楚我想做什么。

thx in advance thx提前

Two solutions spring to mind. 我想到了两种解决方案。

  1. Have the ViewModel hold all the columns and just have the user selected ones on the View. 让ViewModel保存所有列,并在View上只让用户选择一列。 This is not ideal. 这不太理想。

  2. Use reflection on the View data to determine the columns for the ViewModel. 在View数据上使用反射来确定ViewModel的列。

I have done this before in the following way: 我之前通过以下方式完成了这项工作:

  • an XML document is used which describes all the available columns, their formatting (ie "#0.#0" for numeric columns), and the data field they bind to, it also describes which columns are the default ones 使用XML文档描述所有可用列,它们的格式(即数字列的“#0.#0”),以及它们绑定的数据字段,它还描述哪些列是默认列

  • this column description XML is retrieved via a WCF call to the server (this was a Silverlight project) 此列描述XML是通过WCF调用服务器检索的(这是一个Silverlight项目)

  • the grid columns are generated by the View using a grid column factory (this is done by the View because it is heavily UI dependant). 网格列是由View使用网格列工厂生成的(这是由View完成的,因为它依赖于UI)。 The default columns are set to visible, the others are set to not visible 默认列设置为可见,其他列设置为不可见

  • the ViewModel is populated with a list of data objects containing all the data for the columns ViewModel填充了包含列的所有数据的数据对象列表

  • the user can right click on the grid and via the context menu bring up a dialog containing the complete list of columns, with a tick (check) mark next to the ones that are currently visible. 用户可以右键单击网格,然后通过上下文菜单调出一个包含完整列列表的对话框,当前可见的标记旁边有一个勾号(勾号)。 This dialog is managed/populated from the View - as the ViewModel should not know anything about the actual UI. 此对话框由View管理/填充 - 因为ViewModel不应该知道有关实际UI的任何信息。 You may want to use a dialog service for this. 您可能希望使用对话服务。 The dialog's VM is populated with a list of anonymous objects containing the column captions and the visibility state of the column. 对话框的VM将填充一个匿名对象列表,其中包含列标题和列的可见性状态。

  • upon the user closing the dialog the View will show/hide the appropriate columns (i went a step further - as the user checks a column in the dialog it instantly becomes visible in the grid so that the user knows they chose the right one, when displaying many tens of columns quite a few could be very similar). 当用户关闭对话框时,View将显示/隐藏相应的列(我更进一步 - 当用户检查对话框中的列时,它立即在网格中变得可见,以便用户知道他们选择了正确的列,当显示数十列很多可能非常相似)。

The advantage of using the XML document to describe the columns is: 使用XML文档描述列的优点是:

  • it is UI agnostic; 它是UI不可知的; it doesn't matter what grid component i use all i have to do is change the factory 无论我使用什么网格组件我都要做的就是改变工厂

  • the XML document can be updated separately to the code; XML文档可以单独更新为代码; if a client wants a format string changed i don't have to recompile the code. 如果客户端想要更改格式字符串,则不必重新编译代码。 Similarly if i need to show more data in the future all i need to change is my XML document, the assembly containing the data object definitions, and the DAL assembly - the V/VM don't need to be changed at all. 类似地,如果我将来需要显示更多数据,我需要更改的是我的XML文档,包含数据对象定义的程序集和DAL程序集 - V / VM根本不需要更改。

Do you even need to create a view model? 你甚至需要创建一个视图模型吗? Can't you just populate a local DataTable and bind the DataGrid to it? 你不能只填充本地DataTable并将DataGrid绑定到它吗? There's an enormous amount of functionality baked in to the ADO objects, and the DataGrid interoperates with a lot of it. ADO对象中DataGrid了大量功能,而DataGrid与其中很多功能互操作。 If you really need additional properties on the DataRow (like commands, say), you can subclass DataTable and DataRow and add them. 如果你真的需要DataRow上的其他属性(比如命令,比如说),你可以继承DataTableDataRow并添加它们。 This could save you a lot of work. 这可以为您节省大量的工作。

Whether you create a DataTable or create your own class, a fairly simple approach is to set AutoGenerateColumns to true and handle the DataGrid.AutoGeneratingColumn event. 无论是创建DataTable还是创建自己的类,一种相当简单的方法是将AutoGenerateColumns设置为true并处理DataGrid.AutoGeneratingColumn事件。 You can hook in a list of columns that you want to hide, and then set e.Cancel to true when the column being generated is in that list. 您可以挂钩要隐藏的列列表,然后在生成的列位于该列表中时将e.Cancel设置为true。 The documentation shows an example of what this looks like. 文档显示了这个示例的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM