MVVM - How to create columns at runtime for a xamdatagrid?

試著忘記壹切 提交于 2019-12-04 05:34:57

You can use indexers:

In your ViewModel:

public MyVariableCollection RowData
{
    get { return new MyVariableCollection(this); }
}

In MyVariableCollection: protected SomeRowViewModel viewModel;

public MyVariableCollection(SomeRowViewModel viewmodel)
{
    this.viewModel = viewmodel;
}

public object this[string name]
{
    get { return viewModel.GetRowColumnValue(name); }
}

I've tried to keep it brief: but the idea is, you have a new class with an indexer defined, then you can bind like this:

{Binding Path=SomeRowViewModelInstance.RowData["ColumnName"]}

The column collection on the data grid control would be bound - and you could set a column template for each column to bind to the column in question; you needn't use a literal string in the indexer like that.

Hope that provides some food for thought - any questions on this route please leave a comment.


Edit for an additional thought: I have used the contents ComponentModel namespace to produce a custom TypeDescriptor. It is fairly in depth but you can make an object 'appear' to have additional or custom properties. It's far more complex than the indexer method I posted above but if you get stuck it's worth a look.

I had a similar problem because the user was able to define the columns of the grid at runtime.

I wrote a control containing the xam datagrid and exposing a DataSource dependency property to bind the model for the grid (i.e. a data table).

Every time the source changed (you can add event listeners for PropertyChanged and the grids FieldLayoutInitializing event) the grid was dynamically re-rendered by clearing its datasource and resetting it:

private void ReRenderGrid()
{
    XamDataGrid.FieldLayouts.Clear();
    XamDataGrid.ClearValue(DataPresenterBase.DataSourceProperty);
    XamDataGrid.DataSource = DataSource.Data.DefaultView;
}

The columns are re configured by an event handler on the following event which is raised by xamdatagrid after the grids datasource is reset:

XamDataGrid.FieldLayoutInitializing += LayoutInitializing;

Handler:

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));
}

In my case the datasource contained all columns the user configured. AddFields calls this method for each list entry:

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 and AddUnboundField are implemented in a similar fashion.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!