我必须创建一个XamDataGrid,它显示时间范围x到y的动态数量的列。因此,我不知道用户会选择多少年来预先创建这些列。
现在通常在MVVM中,您只需通过XamDataGrid中需要Columns的多个Properties填充数据,后者只需自动生成它们。
显然我不能在运行时在我的ViewModel中创建属性,除非我用Reflection做了一些疯狂的事。
我还能做到这一点吗?
我应该只为数据网格创建未绑定的字段并通过代码填充它们吗?我同意在这个阶段我不需要双向绑定,因为网格只是只读...只是在大声思考。
这种方法是否可以在不违反MVVM模式的情况下进行? 感谢
答案 0 :(得分:4)
您可以使用索引器:
在ViewModel中:
public MyVariableCollection RowData
{
get { return new MyVariableCollection(this); }
}
在MyVariableCollection
中:
protected SomeRowViewModel viewModel;
public MyVariableCollection(SomeRowViewModel viewmodel)
{
this.viewModel = viewmodel;
}
public object this[string name]
{
get { return viewModel.GetRowColumnValue(name); }
}
我试图保持简短:但是想法是,你有一个定义了索引器的新类,那么你可以像这样绑定:
{Binding Path=SomeRowViewModelInstance.RowData["ColumnName"]}
数据网格控件上的列集合将被绑定 - 您可以为每个列设置一个列模板以绑定到相关列;你不需要在索引器中使用像这样的文字字符串。
希望提供一些思考的东西 - 有关此路线的任何问题请发表评论。
编辑以获得额外的想法:我使用了内容ComponentModel
命名空间来生成自定义TypeDescriptor
。它相当深入,但您可以使对象“显示”以具有其他或自定义属性。它比我上面发布的索引器方法复杂得多,但是如果你卡住它就值得一看。
答案 1 :(得分:1)
我遇到了类似的问题,因为用户可以在运行时定义网格的列。
我编写了一个包含xam数据网格的控件,并公开了一个DataSource依赖项属性来绑定网格的模型(即数据表)。
每次源更改(您可以为PropertyChanged添加事件侦听器和网格FieldLayoutInitializing事件)时,通过清除其数据源并重置它来动态重新呈现网格:
private void ReRenderGrid()
{
XamDataGrid.FieldLayouts.Clear();
XamDataGrid.ClearValue(DataPresenterBase.DataSourceProperty);
XamDataGrid.DataSource = DataSource.Data.DefaultView;
}
在重置网格数据源之后,由xamdatagrid引发的以下事件的事件处理程序重新配置列:
XamDataGrid.FieldLayoutInitializing += LayoutInitializing;
处理程序:
private void LayoutInitializing(object sender, FieldLayoutInitializingEventArgs e)
{
const string deletebuttonstyle = "DeleteButtonStyle";
const string requiredinputvalue = "RequiredInputValue";
const string optionalinputvalue = "OptionalInputValue";
const string outputvalue = "OutputValue";
var fieldLayout = e.FieldLayout;
fieldLayout.Fields.Clear();
AddFields(DataSource.InColumns, requiredinputvalue, fieldLayout);
AddSplitter(fieldLayout);
AddFields(DataSource.OptionalInColumns, optionalinputvalue, fieldLayout);
AddSplitter(fieldLayout);
AddFields(DataSource.OutColumns, outputvalue, fieldLayout);
AddUnboundField(fieldLayout, string.Empty, GetStyle(deletebuttonstyle));
}
在我的例子中,数据源包含用户配置的所有列。 AddFields为每个列表条目调用此方法:
private void AddField(string name, Style style, FieldLayout fieldLayout)
{
var field = new Field {Name = name};
field.Settings.LabelPresenterStyle = style;
field.Settings.CellValuePresenterStyle = GetStyle("StandardCellValueStyle");
fieldLayout.Fields.Add(field);
}
AddSplitter和AddUnboundField以类似的方式实现。