【问题标题】:wpf RowDetailsTemplate focuswpf RowDetails模板焦点
【发布时间】:2012-05-09 15:51:33
【问题描述】:

我目前有一个带有 rowdetails 模板的数据网格,其中包含另一个数据网格以显示父子关系。第二个网格有一列包含一个按钮,单击该按钮会显示另一个对话框。

第一次显示行的详细信息时,用户必须在子网格中单击一次以获得焦点/激活它,然后再次单击以触发按钮单击事件。这只会在第一次显示一行时发生。

就像第一次点击被网格吞噬了一样。 我已经尝试捕获 RowDetailsVisibilityChanged 事件来尝试聚焦按钮,但它似乎仍然没有解决问题。

有什么想法吗?

【问题讨论】:

  • 您的 RowDetails DataGrid 是否有不止一行?如果是这样,您是否对所有行都有相同的问题?我怀疑你和这里有同样的问题:stackoverflow.com/questions/7415988/wpf-datagrid-issue
  • 试过设置“focusEnabled=true”吗??
  • @Meleak 感谢您的建议。我的数据网格确实有不止一行。但是帖子中的建议似乎无法解决我的问题。 rowdetails 会自动展开,第一次单击详细信息时,需要单击 2 次才能单击其中包含的按钮。但是,如果我手动循环详细信息(关闭并重新显示它们),则只需单击一下即可。
  • 您手头的问题解决了吗?我遇到了同样的问题。

标签: wpf datagrid


【解决方案1】:

我会回答我自己的评论,它可能也会对其他人有所帮助。 以下 MSDN 条目解释并解决了该问题: http://social.msdn.microsoft.com/Forums/vstudio/en-US/2cde5655-4b8d-4a12-8365-bb0e4a93546f/activating-input-controls-inside-datagrids-rowdetailstemplate-with-single-click?forum=wpf

问题在于始终显示的行详细信息需要首先获得焦点。 为了规避这个问题,需要一个数据网格预览处理程序:

<DataGrid.RowStyle>
    <Style TargetType="{x:Type DataGridRow}"  BasedOn="{StaticResource {x:Type DataGridRow}}">
        <EventSetter Event="PreviewMouseLeftButtonDown" Handler="SelectRowDetails"/>
    </Style>
</DataGrid.RowStyle>

注意:我已经扩展了它,因为它破坏了我的自定义 DataGridRow 样式以继承当前使用的样式。

处理程序本身是

private void SelectRowDetails(object sender, MouseButtonEventArgs e)
{
    var row = sender as DataGridRow;
    if (row == null)
    {
        return;
    }
    row.Focusable = true;
    row.Focus();

    var focusDirection = FocusNavigationDirection.Next;
    var request = new TraversalRequest(focusDirection);
    var elementWithFocus = Keyboard.FocusedElement as UIElement;
    if (elementWithFocus != null)
    {
        elementWithFocus.MoveFocus(request);
    }
}

它将焦点设置在行详细信息的内容上,从而解决了点击两次的问题。

注意:这一切都取自 MSDN 线程,这不是我自己的解决方案。

【讨论】:

  • 多年来我已经多次引用这个答案(我总是忘记,然后不得不搜索它,几个小时后我找到了这个并看到我已经支持它)。谢谢分享这个!!!如果我可以多次投票,我会的。
【解决方案2】:

我找到了一个很好的解决方案:D

我有一行代码可以解决这个问题,但有 10 行代码来描述问题所在。 这是解决方案:

    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        base.OnPropertyChanged(e);

        // to stop RowDetails from eating the first click.
        if (e.Property.Name == "SelectedItem" && CurrentItem == null) CurrentItem = SelectedItem;
    }

请找到详细信息here

【讨论】:

  • 这是一种方法,尽管一些细节会有所帮助;这通过派生类表单 DataGrid 来解决问题,然后在每次网格属性更改时将 SelectedItem 与 CurrentItem 同步。这样做的效果是所选项目始终具有焦点。这样做的缺点是,与其他解决方案相比,它非常浪费。
  • 好吧..说“解决方案”太刻薄了:D
猜你喜欢
  • 2016-09-14
  • 2013-09-17
  • 1970-01-01
  • 1970-01-01
  • 2018-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多