Перенаправленное событие PreviewMouseRightButtonDown и WPF DataGrid
Теперь, в основном, здесь есть два вопроса, позвольте мне мягко представить вам проблему, с которой я столкнулся в данный момент. Допустим, у нас есть обычная DataGrid, и я пытаюсь применить PreviewMouseRightButtonDown
в строке для пользовательских функций и в то же время избегайте выбора, так как это расширяет представление Сведения. Я думал, что этот пост поможет; это было направлено на ListView
, но с небольшими настройками он должен работать так же, верно?
Почему вы хотите это сделать? Вы можете спросить. Я хочу не открывать Подробности при щелчке правой кнопкой мыши, поскольку в главном разделе "Сведения о проекте" (иногда) происходит длительное путешествие в базу данных, и при щелчке правой кнопкой мыши можно установить только соответствующие bool
flag-свойство в представлении модели в коллекции.
MainWindowView.xaml:
<DataGrid AutoGenerateColumns="False" RowDetailsVisibilityMode="VisibleWhenSelected">
<!-- Columns ommitted for brevity -->
<DataGrid.ItemContainerStyle>
<Style TargetType="{x:Type DataGridRow}">
<!-- Since I'm using Caliburn Micro anyway, I'm going to redirect the event to view model. It doesn't really matter, issue exists with EventSetter too. -->
<Setter Property="cal:Message.Attach" Value="[Event PreviewMouseRightButtonDown] = [Action CheckItem($eventArgs, $source]"/>
</Style>
</DataGrid.ItemContainerStyle>
</DataGrid>
MainWindowViewModel.cs:
public void CheckItem(RoutedEventArgs args, object source)
{
var row = source as DataGridRow;
if (row != null)
{
var item = (ItemViewModel)row.Item;
item.IsChecked = true;
}
args.Handled = true;
}
Время вопросов:
- Почему
RoutingStrategy
наRoutedEventArgs
перечислены какDirect
и неTunneling
? Я думал всеPreview
события былиTunneling
,
- И что более важно: вышеуказанное решение работает, если я поставлю точку останова внутри
CheckItem
, выбор не происходит и детали свернуты, все работает как задумано. Если я удалю точку останова, элемент будет выбран, и откроется раздел "Детали", как если бы событие не было остановлено. Почему это происходит? Я думал, что установкаHandled
вtrue
наRoutedEventArgs
следует просто указать, что событие действительно обработано.
[РЕДАКТИРОВАТЬ]
Теперь я нашел обходной обходной путь, я могу просто прикрепить PreviewMouseDown
событие:
bool rightClick;
public void MouseDown(object source, MouseEventArgs args)
{
rightClick = false;
if (args.RightButton == MouseButtonState.Pressed)
{
rightClick = true;
//do the checking stuff here
}
}
а затем подключить к SelectionChanged
событие:
public void SelectionChanged(DataGrid source, SelectionChangedEventArgs args)
{
if (rightClick)
source.SelectedIndex = -1;
}
Это работает для моего конкретного случая, но субъективно выглядит очень вонючей, поэтому я открыт для любых других предложений. Особенно почему простой eventArgs.Handled = true
по событию мыши недостаточно, чтобы подавить выстрел SelectionChanged
позже:)
1 ответ
Обработка PreviewMouseRightButtonUp вместо Down дает желаемый эффект для меня (выбор должен быть сделан вверх, а не вниз?).
На странице msdn для PreviewMouseRightButtonDown говорится, что ее стратегия маршрутизации должна быть "прямой", а на странице " Обзор маршрутизируемых событий" говорится:
Туннельные события также иногда называют предварительными событиями из-за соглашения об именах, которое используется для пар.
Так что, возможно, туннельные события обычно являются предварительными событиями, но это не означает, что предварительные события должны быть туннельными;)
Редактировать:
Если посмотреть на другие события, такие как PreviewMouseDown и MouseDown, то они представляют собой Tunneling и Bubble, хотя, может быть, только события кнопок вправо / влево выполняются как прямые.