处理 DataGrid 内部弹出窗口的Got_Focus和Lost_Focus

Handle Got_Focus & Lost_Focus for Popup inside of DataGrid

提问人:Miraziz 提问时间:1/29/2023 最后编辑:Miraziz 更新时间:1/29/2023 访问量:26

问:

我有一个DataGrid,它有更多选项弹出作为最后一列。当我单击一行的最后一个单元格(更多选项弹出图标)时,弹出窗口将集中并显示,但是在此之后,该行本身立即被选中并将焦点从弹出窗口中移开,这将导致弹出窗口关闭。为了再次打开它,我必须点击两次。

它可以通过设置 来修复,但我希望我的行是可选的。另一种解决方法是尝试将控件集中在事件上,但它也不会给出预期的行为:SelectionMode="None"

PopupBox selectedPopupBox; 

public CustomersView()
{   
    InitializeComponent();
}

private void PopupBox_GotFocus(object sender, RoutedEventArgs e)
{
    var popupBox = sender as PopupBox;
    selectedPopupBox = popupBox;
    popupBox.IsPopupOpen = true;
}

private void CustomersDataGrid_SelectionChanged(object sender, GridSelectionChangedEventArgs e)  
{

    if (selectedPopupBox != null)
    {
        selectedPopupBox.Focus();
        popupBox.IsPopupOpen = true;
    }
}

解决方案的问题在于,每当选择另一行时,都会打开上一个弹出窗口。

我发现的类似问题:Syncfusion 论坛Stackoverflow 问题

PS 我不想在单击一行上的任何其他单元格时打开弹出窗口,只有在单击更多选项图标时才打开弹出窗口。

附加当前行为以使其更清晰:

默认行为:enter image description here

SelectionMode 设置为 Noneenter image description here

使用代码隐藏的解决方法:Workaround with code behind

WPF 数据网格 弹出窗口 SyncFusion 失去焦点

评论

1赞 Sir Rufo 1/29/2023
sf论坛的解决方案不起作用?乍一看,我会说它应该可以完成这项工作
0赞 Miraziz 1/29/2023
哦,没错!我没有注意到下面提供的完整解决方案。谢谢你提到它!

答:

0赞 Miraziz 1/29/2023 #1

这个问题的解决方案是sf论坛的答案。

public partial class CustomersView : UserControl
{
    public CustomersView()
    {
        InitializeComponent();

        this.customersDataGrid.CellRenderers.Remove("TemplateExt");
        this.customersDataGrid.CellRenderers.Add("TemplateExt", new GridCellTemplateExtension());
    }
}

// Create Grid template column extension and specify it's cell type
public class MoreOptionsTemplateColumnExtension : GridTemplateColumn
{
    public MoreOptionsTemplateColumnExtension()
    {
        SetCellType("TemplateExt");
    }
}

public class GridCellTemplateExtension : GridCellTemplateRenderer
{
    // This method will set the focus to the clicked cell
    // instead of row itself
    protected override void SetFocus(FrameworkElement uiElement, bool needToFocus)
    {
        if (!needToFocus)
            DataGrid.Focus();
    }
}

你可以在 XAML 中使用此扩展,如下所示:

<local:MoreOptionsTemplateColumnExtension Width="85"
                                                          AllowFocus="True"
                                                          AllowSorting="False">
                    <local:MoreOptionsTemplateColumnExtension.CellTemplate>
                        <DataTemplate>
                            <md:PopupBox Margin="5"
                                         Padding="2,0,2,0"
                                         HorizontalAlignment="Center"
                                         VerticalAlignment="Center"
                                         Foreground="DarkSlateGray"
                                         PopupMode="Click">
                                <!-- Your popup content -->
                            </md:PopupBox>
                        </DataTemplate>
                    </local:MoreOptionsTemplateColumnExtension.CellTemplate>
                </local:MoreOptionsTemplateColumnExtension>