предотвращение изменения строки в сетке данных

Я исследовал это и зашел в тупик: у меня есть WPF DataGrid и я использую модель MVVM. Я хочу при определенных обстоятельствах предотвратить возможность изменения строки в DataGrid. Я изучил этот вопрос и попробовал такие методы, как найденный здесь.

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

Я удивлен, что нет SelectionChanging или BeforeSelectionChanged, чтобы я мог отменить запуск события; и принудительное предотвращение изменения индекса в моей модели представления, похоже, не имеет никакого значения.

Как я могу это сделать?

Спасибо.


person Mani5556    schedule 26.07.2011    source источник


Ответы (3)


что произойдет, если вы возьмете события previewkeydown и previewmousedown и просто вызовете e.Handled=true при определенных обстоятельствах?

Редактировать: чтобы удовлетворить стиль mvvm: вы можете создать Behavior с DependencyProperty, к которому вы можете привязать свое обстоятельство. в этом поведении вы можете обрабатывать события и, возможно, некоторые другие вещи, например, пользователь нажимает на строку данных или заголовок...

person blindmeis    schedule 26.07.2011
comment
Первое предложение сработало отлично (хотя последнее — очень интересное предложение, и я тоже подумал о том, чтобы попробовать его) — спасибо. - person Mani5556; 26.07.2011

DispatcherPriority имеет значение ContextIdle. Это заставляет вас мерцать, так как ваш SelectedItem установлен дважды (и он был отрендерен дважды). Просто установите приоритет «Нормальный», и мерцания больше не будет.

person Nihad Rizvanovic    schedule 11.01.2012

Есть несколько примеров для метода PreviewMouseDown здесь.

Общее мнение состоит в том, что возврат DataGrid.SelectedItem к исходному значению внутри обработчика SelectionChanged сетки данных не работает должным образом; все примеры кода, которые кажутся работающими, откладывают реверсирование, прося диспетчера запланировать его позже.

У вас есть CellStyle в вашей сетке данных? Для меня сработало следующее:

xaml:

<DataGrid.CellStyle>
    <Style TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="DarkSlateBlue"/>
                <Setter Property="Foreground" Value="White"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</DataGrid.CellStyle>

код программной части:

private void MyDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count > 0)
    {
        object x = e.AddedItems[0];
        if (x is MyObjectType && x != myViewModel.CurrentItem &&
            myViewModel.ShouldNotDeselectCurrentItem())
        {
            // this will actually revert the SelectedItem correctly, but it won't highlight the correct (old) row.
            this.MyDataGrid.SelectedItem = null;
            this.MyDataGrid.SelectedItem = myViewModel.CurrentItem; 
        }
    }
}

Дело в том, что событие SelectedCellsChanged запускается после события SelectionChanged, и, в частности, эта настройка SelectedItem не корректно обновляет SelectedCells, которые являются свойством только для чтения, поэтому больше кода программной части:

private void MyDataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
{
    List<DataGridCellInfo> selectedCells = MyDataGrid.SelectedCells.ToList();

    List<MyObjectType> wrongObjects = selectedCells.Select(cellInfo => cellInfo.Item as MyObjectType)
        .Where (myObject => myObject != myViewModel.CurrentItem).Distinct().ToList();
    if (wrongObjects.Count > 0)
    {
        MyDataGrid.UnselectAllCells();
        MyDataGrid.SelectedItem = null;
        MyDataGrid.SelectedItem = myViewModel.CurrentItem;
    }
}

Очевидно, обработчики должны быть подключены к соответствующим событиям в сетке данных.

Это сработало, как и ожидалось, правильно отменило изменение выбора, если это необходимо, и не вызвало мерцания.

person J S    schedule 24.09.2013