Question

je créer un XamDataGrid qui montre un montant de dynamique de colonnes pour un laps de temps x à y. Par conséquent, je ne sais pas combien d'années un utilisateur choisirait d'avoir ces colonnes créées dès le départ.

usualy au sein MVVM vous serait juste remplir les données par autant de propriétés que vous auriez besoin de colonnes de votre XamDataGrid, et celui-ci serait tout simplement les autogenerate.

Il est évident que je ne pouvais pas simplement créer des propriétés dans mon ViewModel à l'exécution à moins que je l'ai fait quelque chose de fou avec réflexion.

Sinon, comment pourrais-je y parvenir?

Devrais-je créer des champs non liés à la grille de données et de les remplir par le code? Je suis d'accord, je ne vais pas besoin d'un double sens de liaison à ce stade, puisque la grille est seulement ... readonly juste à y penser à haute voix.

Est-ce OK approche sans violer le modèle MVVM? Merci

Était-ce utile?

La solution

Vous pouvez utiliser indexeurs:

Dans votre ViewModel:

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

En MyVariableCollection:     protégé SomeRowViewModel viewmodel;

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

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

J'ai essayé de le garder bref: mais l'idée est, vous avez une nouvelle classe avec un indexeur défini, vous pouvez lier comme ceci:

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

La collection de colonnes sur le contrôle de grille de données serait liée - et vous pouvez définir un modèle de chaque colonne pour se lier à la colonne en question; vous ne devez pas utiliser une chaîne de caractères dans l'indexeur comme ça.

L'espoir qui fournit des éléments de réflexion -. Pour toute question sur cette route s'il vous plaît laisser un commentaire


Modifier une pensée supplémentaire: J'ai utilisé le contenu espace de noms ComponentModel pour produire un TypeDescriptor personnalisé. Il est assez en profondeur, mais vous pouvez faire un objet « Figurer » pour avoir des propriétés supplémentaires ou personnalisées. Il est beaucoup plus complexe que la méthode indexeur ci-dessus mais je posté si vous êtes coincé, il vaut le détour.

Autres conseils

J'ai eu un problème similaire parce que l'utilisateur a pu définir les colonnes de la grille lors de l'exécution.

I a écrit une commande contenant la grille de XAM et l'exposition d'une propriété de dépendance de source de données pour lier le modèle pour le réseau (à savoir un tableau de données).

Chaque fois que la source a changé (vous pouvez ajouter des écouteurs d'événements pour PropertyChanged et les grilles événement FieldLayoutInitializing) la grille a été dynamiquement nouveau rendu en effaçant sa source de données et le réinitialiser:

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

Les colonnes sont re configuré par un gestionnaire d'événement de l'événement suivant qui est soulevée par xamdatagrid après la source de données est remis à zéro grilles:

XamDataGrid.FieldLayoutInitializing += LayoutInitializing;

Gestionnaire:

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

Dans mon cas, la source de données contient toutes les colonnes de l'utilisateur configuré. AddFields appelle cette méthode pour chaque entrée de la liste:

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 et AddUnboundField sont mises en œuvre de façon similaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top