WPF 行详细信息模板焦点

5

我目前有一个数据网格,其中包含另一个数据网格以显示父子关系。第二个网格有一列包含一个按钮,当点击时会显示另一个对话框。

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

就像第一次单击被表格吞噬了一样。 我尝试捕获RowDetailsVisibilityChanged事件来尝试聚焦按钮,但似乎仍未解决该问题。

有什么想法吗?


3
您的RowDetails DataGrid是否有多行?如果是,所有行都有同样的问题吗?我怀疑您遇到了与此处相同的问题:https://dev59.com/-lvUa4cB1Zd3GeqPrkL3 - Fredrik Hedblad
尝试过设置“focusEnabled=true”吗? - code90
1
@Meleak 感谢您的建议。我的数据网格确实有多行。然而,帖子中的建议似乎不能解决我的问题。行详细信息会自动展开,第一次单击详细信息时,需要单击两次其中包含的按钮。但是,如果我手动循环详细信息(关闭并重新显示它们),则只需要单击一次。 - seanzi
你解决了手头的问题吗?我遇到了同样的问题,看到了这个帖子。 - Samuel
2个回答

6
我会回答自己的评论,可能也会帮到其他人。 下面的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预览处理程序。
<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线程,不是我的解决方案。


多年来,我已经多次引用了这个答案(我总是忘记,然后不得不搜索它,经过几个小时我找到了它,并看到我已经点赞了)。感谢分享!!!如果我可以多次点赞,我一定会的。 - Tronald

1
我找到了一个好的解决方案 :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;
    }

并且请在这里查找详细信息。


1
这是一种方法,尽管一些细节会很有帮助;这通过从DataGrid派生一个类来解决问题,然后每次网格的属性更改时将SelectedItem与CurrentItem同步。这样做的效果是所选项目始终具有焦点。缺点是与其他解决方案相比非常浪费资源。 - Timothy Groote
嗯,是的...说“THE solution”太刻薄了:D - Ashi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接