Problem

PopupButton closes when manipulating a TreeView within it

Posted 5 years ago by Avatar Craig - Varigence, Inc.
I'm hitting a case where I have a PopupButton that contains a TreeView but the button undesireably closes when I click on TreeView's elements.

The scenario is that I have a .NET 4.0 datagrid with a template column. The cell template is a textblock but the editing template contains a PopupButton. Within the PopupButton is the ResizableContentControl, which is displaying a user control. Within the UserControl is a TreeView. I'm seeing that whenever I click on a TreeViewItem or the expander arrow of a TreeView item, the popup closes immediately. This is problematic since I want the user to be able to select items and navigate the treeview without having to keep reopening the popup. Interestingly, when I click on a TreeViewItem's expander and then reopen the popup (since it closed on the click), I see that the TreeViewItem has expanded.

I'll send over a sample app that should reproduce the scenario for you.

Thanks,

-Craig

Comments (8)

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Hi Craig,

Thanks for the sample. Unfortunately, this appears to be an issue with the DataGridCell. Basically, when you click the cell exits the "edit mode", thus hiding the PopupButton (which in turn closes the popup). If you try to use the PopupButton outside of the DataGrid, you will see it works correctly.

The related code can be seen in DataGridCell.OnAnyMouseLeftButtonDown, which is hooked up to be called for unhandled and handled events. I'm not sure what can be done to prevent the DataGridCell from exiting "edit mode".

Actipro Software Support
Posted 5 years ago by Craig - Varigence, Inc.
I reached a similar conclusion when I first looked at this issue myself so it looks like we're in agreement as to the problem. :)

Looking at OnAnyMouseLeftButtonDown, how could it be changed to avoid this issue? Is it a matter of checking for e.Handled in the else-if statement, along with trying to set e.Handled in my code? Would we need to avoid the Focus call? Something else?

Thanks,

-Craig

[Modified at 04/23/2010 12:48 PM]
Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Hi Craig,

You would probably be better posing this question on Microsoft's forum for the DataGrid. But it seems like the DataGridCell code would need to be overridden/changed to check to see if a Popup is open, which is a child of the cells editing template.

Actipro Software Support
Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
One thought though, you may be able to give the PopupButton focus when it's popup is opened to by-pass the closing code. I don't think it will currently take focus when you click the expansion portion.

Actipro Software Support
Posted 5 years ago by Craig - Varigence, Inc.
So, I was able to sort of solve it by doing the following:

1. Add an event handler to the datagrid for the CellEditEnding event.
2. In the handler, add the following:
private static void DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    if (e.Column.GetType() == typeof(DataGridTemplateColumn))
    {
        var popup = WpfHelper.GetVisualChild<Popup>(e.EditingElement);
        if (popup != null && popup.IsOpen)
        {
            e.Cancel = true;
        }
    }   
}
This stops the edit from being cancelled when the popup is open. The only limitation is that when clicking outside the popup, it does keep the popup button visible (but closed) in the cell. Another click in the datagrid will then get the cell out of edit mode.

I did try the focus approach you mentioned but it didn't seem to help.

My question is that while my above approach does allow me to use my treeview, I can't click inside the textbox above it to type in it. I see that the GotFocus and PreviewMouseDown handlers fire, but the MouseDown handler is never hit. Could the PopupButton or ResizableContentControl be redirecting the MouseDown event so it doesn't reach the TextBox?

Thanks again,

-Craig
Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Hi Craig,

I don't know to which TextBox you are referring. Your sample had one below the DataGrid, but after adding your code I can click in there fine.

Actipro Software Support
Posted 5 years ago by Craig - Varigence, Inc.
Oh sorry, I was referring to my own application. I've sent over a new sample that includes the textbox with the treeview so you can see a repro of the new issue.

Thanks,

-Craig

[Modified at 04/28/2010 01:53 AM]
Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Hi Craig,

Sorry, but I think this is the same issue, where the DataGridCell is handling the mouse down event. If you hook up to the MouseLeftButtonDown event on the PopupButton or TextBox, you'll see that event is never raised. Additionally, if you move the PopupButton outside of the DataGrid then it works as expected.

Again, you would probably be better posing this question on Microsoft's forum for the DataGrid, as they may know a workaround.

Actipro Software Support

Add a Comment

Please log in to a validated account to post comments.