PreviewMouseRightButtonDown路由事件和WPF DataGrid

时间:2012-08-04 23:01:42

标签: c# wpf wpfdatagrid routed-events

现在基本上有两个问题,让我轻轻地向您介绍我目前遇到的问题。假设我们有一个常规的DataGrid,我尝试在行上应用PreviewMouseRightButtonDown以获得自定义功能,同时避免选择,因为这会扩展Details视图。我以为this post would help; it was directed at ListView, but with few adjustment it should work the same, right?


你为什么要这样做?,你可能会问。 我想避免在右键单击时打开详细信息,因为在主项目“详细信息”部分中进行了(有时)冗长的数据库访问,右键单击只会在视图模型中设置相应的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列为。{1}} Direct而非Tunneling?我以为所有Preview事件都是 Tunneling

enter image description here

  • 更重要一点:如果我在CheckItem内放置断点,上面的解决方案有效,选择不会发生,细节会崩溃,一切正常 如预期。如果我删除了断点,则选择项目并且 详细信息部分打开,就像事件未停止一样 传播。为什么会这样?我以为那个设定了 Handled上的trueRoutedEventArgs应该只是表明 事件真的是处理

[编辑]

现在我找到了一个'肮脏'的解决方法,我可以附加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 个答案:

答案 0 :(得分:0)

处理PreviewMouseRightButtonUp而不是Down可以为我获得所需的效果(选择必须在up而不是down?)。

PreviewMouseRightButtonDown的msdn页面表示其路由策略应为“Direct”,Routed Events Overview页面显示:

  

隧道事件有时也称为预览事件,   因为用于对的命名约定。

所以隧道事件通常都是预览事件,但它并不是说预览事件必须是隧道效应;)

编辑:

看看其他事件,比如PreviewMouseDown和MouseDown,它们是隧道和泡泡,也许只是右/左按钮事件是直接完成的。