MVVM - Как создать столбцы во время выполнения для xamdatagrid?

Мне нужно создать XamDataGrid, который показывает динамическое количество столбцов для периода времени от x до y. Поэтому я не знаю, сколько лет пользователь выбрал бы, чтобы эти столбцы создавались заранее.

Теперь обычно в MVVM вы просто заполняете данные через столько свойств, сколько вам нужно, чтобы столбцы в вашей XamDataGrid, а последние просто генерируются автоматически. их.

Очевидно, что я не мог бы просто создать Свойства в моей ViewModel во время выполнения, если я не сделал что-то сумасшедшее с Reflection.

Как еще я мог бы достичь этого?

Должен ли я просто создать несвязанные поля для сетки данных и заполнить их через код? Я согласен, что мне не нужно двухстороннее связывание на этом этапе, так как сетка только для чтения ... просто думает громко.

Оправдан ли этот подход, не нарушая паттерн MVVM?

Теперь обычно в MVVM вы просто заполняете данные через столько свойств, сколько вам нужно, чтобы столбцы в вашей XamDataGrid, а последний просто генерирует их автоматически.

Очевидно, я не мог просто создать свойства в моей ViewModel во время выполнения. если я не сделал что-то сумасшедшее с Reflection.

Как еще я мог бы достичь этого?

Должен ли я просто создать несвязанные поля для сетки данных и заполнить их с помощью кода? Я согласен, что мне не нужно двухстороннее связывание на этом этапе, так как сетка только для чтения ... просто думает громко.

Оправдан ли этот подход, не нарушая паттерн MVVM?

Теперь обычно в MVVM вы просто заполняете данные через столько свойств, сколько вам нужно, чтобы столбцы в вашей XamDataGrid, а последний просто генерировал их автоматически.

Очевидно, что я не мог просто создать свойства в моей ViewModel во время выполнения. если я не сделал что-то сумасшедшее с Reflection.

Как еще я мог бы достичь этого?

Должен ли я просто создать несвязанные поля для сетки данных и заполнить их с помощью кода? Я согласен, что мне не нужно двухстороннее связывание на этом этапе, так как сетка только для чтения ... просто думает громко.

Оправдан ли этот подход, не нарушая паттерн MVVM?

Как еще мне этого добиться?

Должен ли я просто создать несвязанные поля для сетки данных и заполнить их с помощью кода? Я согласен, что мне не нужно двухстороннее связывание на этом этапе, так как сетка только для чтения ... просто думает громко.

Оправдан ли этот подход, не нарушая паттерн MVVM?

Как еще мне этого добиться?

Должен ли я просто создать несвязанные поля для сетки данных и заполнить их с помощью кода? Я согласен, что мне не нужно двухстороннее связывание на этом этапе, так как сетка только для чтения ... просто думает громко.

Оправдан ли этот подход, не нарушая паттерн MVVM? Спасибо

7
задан Athena Widget 24 December 2015 в 16:10
поделиться

2 ответа

Вы можете использовать индексаторы:

В вашей 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 . Это довольно подробно, но вы можете заставить объект «казаться» имеющим дополнительные или настраиваемые свойства. Это намного сложнее, чем метод индексатора, который я опубликовал выше, но если вы застряли, на него стоит взглянуть.

5
ответ дан 7 December 2019 в 09:55
поделиться

У меня была аналогичная проблема, потому что пользователь мог определять столбцы сетки во время выполнения.

Я написал элемент управления, содержащий сетку данных 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 реализованы аналогичным образом.

1
ответ дан 7 December 2019 в 09:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: