Miraziz
Miraziz

Reputation: 509

Handle Got_Focus & Lost_Focus for Popup inside of DataGrid

I have a DataGrid which has more options popup as a last column. When I click on a last cell of a row (more options popup icon) popup will get focused and show up, however instantly after that the row itself gets selected and will take focus away from popup which will cause the popup to close. In order to open it again I have to click twice on it.

It could be fixed by setting SelectionMode="None", but I want my rows to be selectable. Another workaround could be to try control focuses on events, but it also doesn't give an expected behavior:

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

The problem with the solution would be that whenever another row will be selected previous popup will be opened.

Similar problems I found: Syncfusion forum, Stackoverflow question

P.S. I don't want to open a popup when any other cell on a row is clicked, only when more options icon is clicked.

Attaching current behaviors to make it more clear:

Default behavior: enter image description here

SelectionMode is set to None: enter image description here

Workaround with code behind: Workaround with code behind

Upvotes: 0

Views: 36

Answers (1)

Miraziz
Miraziz

Reputation: 509

The solution to this problem was the answer from sf forum.

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

And you can you use this extension in your XAML like this:

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

Upvotes: 0

Related Questions