现在这里基本上有两个问题,让我轻轻地向您介绍一下我目前遇到的问题。假设我们有一个常规的 DataGrid,我尝试PreviewMouseRightButtonDown
在行上应用自定义功能,同时避免选择,因为这会扩展 Details 视图。我认为这篇文章会有所帮助;它是针对 的ListView
,但只需稍作调整,它应该可以正常工作,对吗?
你为什么想这么做?,你可能会问。我想避免在右键单击时打开详细信息,因为在主项目详细信息部分中(有时)会花费很长时间访问数据库,并且右键单击只会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
[编辑]
现在我找到了一个“低俗”的解决方法,我可以附加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
以后的触发:)