Pergunta

Eu tenho que criar um xamdataGrid que mostra uma quantidade dinâmica de colunas para um período de tempo x a y. Portanto, não sei quantos anos um usuário selecionaria que essas colunas criassem antecipadamente.

Agora, de sempre no MVVM, você apenas preencheria os dados por tantas propriedades quanto precisaria de colunas dentro do seu XamdataGrid, e as últimas apenas as autogeririam.

Obviamente, eu não podia simplesmente criar propriedades dentro do meu viewmodel em tempo de execução, a menos que eu fizesse algo louco com reflexão.

De que outra forma eu conseguiria isso?

Devo apenas criar campos não ligados para o datagrid e preenchê -los através do código? Eu concordo que não precisará de uma ligação bidirecional nesta fase, já que a grade está apenas rerontamente ... só de pensar em barulho.

Essa abordagem está OK sem violar o padrão MVVM? Obrigado

Foi útil?

Solução

Você pode usar indexadores:

Em seu viewmodel:

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

Dentro MyVariableCollection: protegido SomrowViewModel ViewModel;

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

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

Eu tentei mantê -lo breve: mas a idéia é que você tem uma nova classe com um indexador definido, então você pode se vincular assim:

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

A coleção de colunas no controle da grade de dados seria vinculada - e você pode definir um modelo de coluna para cada coluna para se ligar à coluna em questão; Você não precisa usar uma corda literal no indexador como esse.

Espero que forneça um pouco de alimento para o pensamento - qualquer dúvida nesta rota, por favor, deixe um comentário.


Editar para um pensamento adicional: usei o conteúdo ComponentModel namespace para produzir um costume TypeDescriptor. É bastante profundo, mas você pode fazer com que um objeto 'pareça' ter propriedades adicionais ou personalizadas. É muito mais complexo do que o método indexador que publiquei acima, mas se você ficar preso, vale a pena dar uma olhada.

Outras dicas

Eu tive um problema semelhante porque o usuário conseguiu definir as colunas da grade em tempo de execução.

Escrevi um controle contendo o Xam DataGrid e expondo uma propriedade de dependência de dados de dados para vincular o modelo para a grade (ou seja, uma tabela de dados).

Toda vez que a fonte era alterada (você pode adicionar ouvintes de eventos para o PropertyChanged e o Evento Grids FieldLayoutinitialize), a grade foi renderizada dinamicamente ao limpar seu painel de dados e redefini-lo:

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

As colunas são configuradas por um manipulador de eventos no evento a seguir, que é levantado pelo XamdataGrid após a redefinição do conjunto de dados da grade:

XamDataGrid.FieldLayoutInitializing += LayoutInitializing;

Manipulador:

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

No meu caso, o DataSource continha todas as colunas que o usuário configurou. Addfields chama esse método para cada entrada da lista:

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 e Addunboundfield são implementados de maneira semelhante.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top