wpf RowDetailsTemplate 焦点

问题描述 投票:0回答:3

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

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

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

有什么想法吗?

wpf datagrid
3个回答
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.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线程,这不是我自己的解决方案。


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

请在此处查找详细信息。


0
投票

这是我在这里的第一篇文章,所以我无法发表评论...

因为这让我抓狂了一段时间,所以我想在 Samuels 的答案中添加一行(这实际上是一个很好的解决方案)。

我遇到了问题,我无法从DetailsView内的ComboBox中选择项目,因为焦点始终设置为DataGridRow,因此为了避免重新聚焦并使解决方案更稳定,我添加了检查

if(row.IsKeyboardFocusWithin) return;

所以完整的代码如下所示:

private void SelectRowDetails(object sender, MouseButtonEventArgs e)
{
    var row = sender as DataGridRow;
    if (row == null || row.IsKeyboardFocusWithin)
    {
        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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.