【问题标题】:PreviewMouseRightButtonDown routed event and WPF DataGridPreviewMouseRightButtonDown 路由事件和 WPF DataGrid
【发布时间】:2012-08-04 23:01:42
【问题描述】:

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


你为什么要这样做?,你可能会问。 我想避免在右键单击时打开详细信息,因为在主项目详细信息部分中(有时)会花费很长时间访问数据库,而右键单击只会在集合中的视图模型中设置适当的bool flag-property .


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;
}

提问时间:

  • 为什么RoutedEventArgs 上的RoutingStrategy 被列为 Direct 而不是 Tunneling?我以为所有Preview 事件都是 Tunneling

  • 更重要的是:如果我在CheckItem 中放置一个断点,上述解决方案有效,选择不会发生并且详细信息已折叠,一切正常 如预期。如果我删除断点,则会选择项目并 详细信息部分打开,就好像事件没有停止一样 传播。为什么会这样?我以为设置 RoutedEventArgs 上的 Handledtrue 应该只表明 事件确实得到处理

[编辑]

现在我找到了一个“低俗”的解决方法,我可以附上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 事件触发,它本质上与使用&lt;EventSetter Event="PreviewMouseRightButtonDown" Handler="CheckItem"/&gt; 相同,但是这样你必须在视图后面的代码中处理事件,将事件附加到 Caliburn 附加的 Micro属性使您能够在视图模型中处理此问题。尽管如此,即使您使用 EventSetter 并在代码隐藏中执行所有操作,它仍然是相同的 - 事件通过,详细信息行打开。

标签: c# wpf wpfdatagrid routed-events


【解决方案1】:

处理 PreviewMouseRightButtonUp 而不是 Down 可以获得我想要的效果(选择必须在 up 而不是 down 上完成?)。

PreviewMouseRightButtonDown 的 msdn 页面说它的路由策略应该是“直接”,Routed Events Overview 页面说:

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

所以也许隧道事件通常是预览事件,但并不是说预览事件必须是隧道;)

编辑:

查看其他事件,例如 PreviewMouseDown 和 MouseDown,它们是 Tunneling 和 Bubble,也许只是右/左按钮事件是直接完成的。

【讨论】:

  • 你说得对,PreviewMouseRightButtonUp 按我的意愿工作。奇怪的事情虽然PreviewMouseDown 没有...无论如何,感谢您指出这一点,我在这些事件中混淆了太多,所以我什至没有尝试Up 版本。 :) 既然它解决了我的主要问题,我会将其标记为答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-18
  • 1970-01-01
  • 2012-05-10
  • 1970-01-01
  • 2016-06-30
  • 2011-04-22
  • 1970-01-01
相关资源
最近更新 更多