WPG DataGrid AutoGeneratingColumn не сработал надежно - PullRequest
1 голос
/ 07 февраля 2020

Я использую WPF DataGrid , у которого ItemsSource связан с некоторым свойством MyResults, где MyResults - это DefaultView экземпляра DataTable . Поскольку мне нужна некоторая гибкость в маркировке заголовков столбцов в DataGrid, я подписываюсь на событие AutoGeneratingColumn для настройки этих заголовков.

View / XAML:

<DataGrid x:Name="ResultTable" ItemsSource="{Binding MyResults, Mode=OneWay}"
  cal:Message.Attach="[Event AutoGeneratingColumn] = [Action CustomizeAutoColumn($this, $eventArgs)]"
  AutoGenerateColumns="True"/>

ViewModel / CS:

public DataView MyResults { get { return MyDataTable.DefaultView; } }

public void CustomizeAutoColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) {
    e.Column.Header = AdjustHeaderText(e.Column.Header);
}

Количество столбцов в MyDataTable может изменяться динамически, требуя, чтобы DataGrid обновлял свои автоматически созданные столбцы. В этом случае запускается следующая функция в ViewModel (подкласс Caliburn.Micro.Screen):

private void UpdateResultTable() { // not working
    NotifyOfPropertyChange(() => MyResults);
}

Моя проблема в том, что событие AutoGeneratingColumn никогда не запускается с этой реализацией (или, по крайней мере, CustomizeAutoColumn) никогда не называется). Ни во время инициализации программы (что является моей первой проблемой), ни при вызове UpdateResultTable (вторая проблема). Хотя новое содержимое строки добавляется в представление, как и ожидалось, столбцы остаются такими, как есть.

Я нашел обходной путь, получив дескриптор объекта View в моей ViewModel, явно сбросив источник элементов. Однако это, очевидно, довольно уродливо, тем более что оно нарушает разделение View / ViewModel. Обратите внимание, что, поскольку я использую Caliburn Micro, у меня нет кода для представления XAML.

private void UpdateResultTable() { // working
    var datagrid = VisualTree.FindChild<DataGrid>((DependencyObject)GetView(), "ResultTable");
    datagrid.ItemsSource = null;
    datagrid.ItemsSource = MyResults;
}

Есть идеи, как получить первоначальный подход к работе? Заранее спасибо за любые предложения!

1 Ответ

0 голосов
/ 10 февраля 2020

явно сбрасывает источник предметов. Однако это, очевидно, довольно уродливо, тем более что оно нарушает разделение View / ViewModel.

Не безобразно само по себе, но требуется.

Но для соблюдения такого разделения виртуальная машина должна предоставить команду (ICommand), которая запрашивает, чтобы представление сбрасывало текст данных, на который подписано представление. Следовательно, отдельный.

Я сделал это по тем же причинам, и вот код для сброса запрашиваемого изменения VM:

public MainWindow()
{
    DataContext = VM = new CertifyingVM();

    VM.CommandRefreshBindings = new OperationCommand(o =>
    {
        MainAccessionHeader.DataContext =
        MainHeader.DataContext = null;

        MainAccessionHeader.DataContext =
        MainHeader.DataContext = VM;

        var currentBatch = VM.CurrentBatch;
        MainAccessionHeader.CurrentBatch = null;
        MainAccessionHeader.CurrentBatch = currentBatch;

    });

    VM.LockBatchGui = new OperationCommand(o =>
    { ... }

OperationCommand is моя ICommand операция, которая продемонстрирована в моем блоге под названием Xaml: MVVM Пример для более простой привязки .

То, как вы запускаете, зависит от вас, просто удалите значение datacontext в null, а затем установите его обратно.

...