Теперь в основном здесь есть два вопроса, позвольте мне просто познакомить вас с проблемой, с которой я сталкиваюсь в данный момент. Предположим, у нас есть обычный DataGrid, и я стараюсь применять PreviewMouseRightButtonDown
в строке для пользовательских функций и в то же время избегать выбора, так как это расширяет представление Details. Я думал, что this post would help; it was directed at ListView
, but with few adjustment it should work the same, right?PreviewMouseRightButtonDown маршрутизированное событие и WPF DataGrid
Почему вы хотите сделать это?, вы можете спросить. Я хочу, чтобы не открывать детали в правом щелчке, потому что в главном разделе «Детали проекта» (иногда) длительная поездка в базу данных, и щелчок правой кнопкой мыши установит только подходящее значение флага-типа bool
в модели просмотра в коллекции.
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
должна указывать только , что событие действительно обработано.
[EDIT]
Теперь я нашел 'неряшливый' обходной путь, я могу просто прикрепить 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
позже :)
@Blam Событие срабатывает, так же важно, как использовать ' ', но таким образом вам придется обрабатывать событие в коде, стоящем за представлением , присоединение события к подключенному к Caliburn's микроуровневому свойству позволяет вам справиться с этим в модели представления. Тем не менее, даже если вы используете «EventSetter» и делаете все по коду, все равно одно и то же - событие проходит, открывается строка сведений. –