Frage

Ich habe einen XamDataGrid zu schaffen, dass zeigt eine dynamische Größe von Spalten für einen Zeitrahmen x bis y. Ich nicht deshalb wissen, wie viele Jahre ein Benutzer diese Spalten erstellt im Voraus hätte wählen.

Jetzt usualy innerhalb MVVM würden Sie nur die Daten, die durch so viele Eigenschaften füllen, wie Sie Spalten in Ihrer XamDataGrid brauchen würden, und dieser würde sie nur automatisch generieren.

Natürlich konnte ich nicht einfach erstellen Eigenschaften in meinem Ansichtsmodell zur Laufzeit, wenn ich etwas Verrücktes mit Reflexion habe.

Wie sonst würde ich das erreichen?

Sollte ich nur ungebundene Felder für die Datenraster und füllen Sie sie durch den Code? Ich bin damit einverstanden Ich werde nicht einen Zweiweg brauchen in diesem Stadium Binding, da das Gitter nur Read-only ist ... nur daran denke laut.

Ist dieser Ansatz OK, ohne das Muster MVVM zu verletzen? Dank

War es hilfreich?

Lösung

Sie können Indexer verwenden:

In Ihrem Ansichtsmodell:

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

In MyVariableCollection:     geschützt SomeRowViewModel Ansichtsmodell;

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

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

Ich habe versucht, es kurz zu halten: aber die Idee ist, haben Sie eine neue Klasse mit einem Indexer definiert ist, dann können Sie wie folgt binden:

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

Die Spalte Sammlung auf der Datenraster Kontrolle würde gebunden werden - und man konnte eine Spalte Vorlage für jede Spalte zu binden an die Säule in Frage gesetzt; Sie brauchen nicht eine Zeichenkette in den Indexer wie diese verwenden.

Hoffnung, dass einige zum Nachdenken bietet -. Fragen auf dieser Strecke lassen Sie einen Kommentar


Bearbeiten für einen weiteren Gedanken: Ich habe den Inhalt ComponentModel Namespace verwendet, um eine benutzerdefinierte TypeDescriptor zu produzieren. Es ist ziemlich in der Tiefe, aber Sie können ein Objekt ‚erscheinen‘ zusätzliche oder benutzerdefinierte Eigenschaften haben, machen. Es ist viel komplexer als die Indexer Methode, die ich oben geschrieben, aber wenn Sie bekommen es lohnt sich ein Blick fest.

Andere Tipps

Ich hatte ein ähnliches Problem, da der Benutzer in der Lage war, zur Laufzeit der Spalten des Gitters zu definieren.

Ich schrieb eine Steuerung der XAM Datenraster enthält, und eine Datasource-Abhängigkeitseigenschaft Belichten das Modell für das Gitter zu binden (d.h. eine Datentabelle).

Jedes Mal, wenn die Quelle geändert das Gitter wurde dynamisch seine Datenquelle neu gerendert (Sie Ereignis-Listener für Property und die Gitter FieldLayoutInitializing Ereignis hinzufügen können) durch Löschen und Zurücksetzen es:

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

Die Spalten werden wieder von einem Event-Handler auf dem folgende Ereignisse konfiguriert, die durch xamdatagrid nach dem Gitter Datenquelle erhöht wird, wird zurückgesetzt:

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 meinem Fall enthielt die Datenquelle alle Spalten der Benutzer konfiguriert. AddFields ruft diese Methode für jeden Listeneintrag:

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 und AddUnboundField werden auf ähnliche Art und Weise umgesetzt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top