Select to view content in your preferred language

How can I capture the event when my custom dockpane is closed?

2940
9
Jump to solution
04-25-2019 11:43 AM
KhamilleJaynes
Emerging Contributor

Hi! I want to learn how to capture when my custom dockpane is closed. I would like to handle this event by saving whether the dockpane was left open or closed. 

I found this resource (ProConcepts Framework · Esri/arcgis-pro-sdk Wiki · GitHub ) but I'm not sure if it's related, because I put this code into my Module.cs file:

protected override void OnPaneClosed(Pane pane)
{
   //...
}
and added a breakpoint in VisualStudio 2017. I ran my program and when I closed my custom dockpane, the breakpoint wasn't hit. 

I thought that there might be an event related to panes that I could subscribe OnPaneClosed() to but I didn't find anything that sounded like what I need.
0 Kudos
1 Solution

Accepted Solutions
UmaHarano
Esri Regular Contributor

Hi

The Dockpane class has an OnShow override that can be used to determine when the Dockpane is visible or closed.  Here is the method snippet below.  The parameter passed to this method will be true if the Dockpane is being opened and it is false when you close the dockpane.

 protected override void OnShow(bool isVisible)
        {
            System.Diagnostics.Debug.WriteLine($"Visible: {isVisible}");            
        }

Note: Dock panes are singletons—there is never more than one instance of a particular dock pane—and once created, they are not destroyed until the application is closed.  They are only "hidden" when you close it.

Thanks

Uma

View solution in original post

9 Replies
ModyBuchbinder
Esri Regular Contributor

Hi

I found a way to do it but this is not MVVM at all...

In my xaml in the DockPane I set <DockPane ....Unloaded="DockPanel_Unloaded">

Then I have a routine in my class of the xaml (and NOT in my modelView) looks like this:

private void DockPanel_Unloaded(object sender, RoutedEventArgs e)

It is called and working.

I tried to put in xaml  Unloaded="{Binding closePane}" but could not make it working.

Anybody?

0 Kudos
UmaHarano
Esri Regular Contributor

Hi

The Dockpane class has an OnShow override that can be used to determine when the Dockpane is visible or closed.  Here is the method snippet below.  The parameter passed to this method will be true if the Dockpane is being opened and it is false when you close the dockpane.

 protected override void OnShow(bool isVisible)
        {
            System.Diagnostics.Debug.WriteLine($"Visible: {isVisible}");            
        }

Note: Dock panes are singletons—there is never more than one instance of a particular dock pane—and once created, they are not destroyed until the application is closed.  They are only "hidden" when you close it.

Thanks

Uma

ModyBuchbinder
Esri Regular Contributor

Hi Uma

Thanks, it works (why is the intellisense does not show this option?).

Let me take it one step foreword.

The reason I need this is to clean some combo boxes.

I have some input form to enter field values. If the user reopen the dock to enter new record I would like the combo to return to empty just like the first time the dock was opened.

Below is a short snippet of my code, I need the select source to be empty even if it has some value the last time the dock was visible.

Thanks

       protected override void OnShow(bool isVisible)
        {
            //System.Windows.MessageBox.Show("h");
            if(isVisible == true)
            {
                _SelectList1 = "";
                NotifyPropertyChanged(() => SelectSource) ;
            }
        }
        
        public string SelectSource
        {
            get
            { return _SelectList1; }
            set
            { SetProperty(ref _SelectList1, value, () => SelectSource); }
        }
        

        
        public ObservableCollection<string> List1
        {
            get
            {
                
                if (_List1 == null)
                {
                    _List1 = new ObservableCollection<string>();
                    _List1.Add("one");
                    _List1.Add("two");
                    _List1.Add("three");
                }
                return _List1;
            }
            set
            {
                SetProperty(ref _List1, value, () => _List1);
            }
        }
0 Kudos
KhamilleJaynes
Emerging Contributor

Hi Uma,

This worked perfectly for what I wanted to achieve. Thank you!

0 Kudos
KarthikAditya
Occasional Contributor

Thank you for the snippet.

However, the OnShow method is called not only when the DockPane is opened or closed but also when it's auto hidden - collapsed into the non-client area.

Is there a way to distinguish when the DockPane is closed and when its auto-hidden?

0 Kudos
Amadeus111
Frequent Contributor

@UmaHarano is it possible to use this for a dockpane coming from another addin. 

In my case, my main dockpane supposed to control another dockpane (dependent) that is attached to another addin. I am passing dockpaneid from categories/components and able to control it via a checkbox. However, I cant detect the event when user decides to close the dockpane via its pane by using X. 

Is there a solution for that? Thanks!

0 Kudos
YeongHwaShih
New Contributor

If you are docking the pane then "Unloaded" also get triggered then how to distinguish either Close or Docking?

0 Kudos
DavidWilton
Frequent Contributor

The code you site is supposed to be in the module. However, these relate to Panes not DockPanes. I still haven't found a reliable way to tell if a dockpane has been closed with the X

 

internal sealed class MainModule : Module
{

protected override void OnPaneClosing(Pane pane, CancelRoutedEventArgs e)
{
Debug.WriteLine("OnPaneClosing");
}

protected override void OnPaneClosed(Pane pane)
{
Debug.WriteLine("OnPaneClosed");
}
protected override void OnPaneOpened(Pane pane)
{
Debug.WriteLine("OnPaneOpened");
}
protected override void OnPaneActivated(Pane incomingPane)
{
Debug.WriteLine("OnPaneActivated");
}
protected override void OnPaneDeactivated(Pane outgoingPane)
{
Debug.WriteLine("OnPaneDeactivated");

}

 

//
// Summary:
// Called by the Framework when one of the Module's Pane is about to close.
//
// Parameters:
// pane:
// The Pane being closed.
//
// e:
// The event data associated with the closing event. Set the Cancel property to
// false to cancel the action.
//
// Remarks:
// Modules are automatically notified whenever one of its panes are activated, deactivated,
// opened, or closed. This means a Module doesn’t have to listen to the Framework’s
// ActivePaneChanged event and from here filter for its panes; instead, Modules
// are given direct notification that one of their panes changed.
protected internal virtual void OnPaneClosing(Pane pane, CancelRoutedEventArgs e)
{
}

 

 

0 Kudos
DavidWilton
Frequent Contributor

OK so 5 years later.. I really thought other people would need to know the difference between the user clicking the X on the pane and just clicking away from it. The problem with the onShow suggested by @UmaHarano is that if fires if the user clicks on another pane in the same group and it is hidden beind another pane.

I couldn't find a simple solution for this. What we need to listen for is the pane.DocState. You'd think we could just check it within OnShow, but the dock state has not yet been set when the pane is hidden and the user has clicked X. Or just listen to the onPropertyChanged and listen to the dock state, but it doesn't seem to fire.

What I ended up doing was this:

In the XAML of your dockpane add 

<UserControl x:Class="ArcGISProTools.ViewModels.MyDockPaneView"
Unloaded="UserControl_Unloaded

In the code behind (MyDockPaneView.cs) add this

private void UserControl_Unloaded(object sender, RoutedEventArgs e)
{
   DockPane pane =    ArcGIS.Desktop.Framework.FrameworkApplication.DockPaneManager.Find(MyDockPaneViewModel.DockPaneID);
   var vm = (MyDockPaneViewModel)this.DataContext;
   if (pane != null)
      {
           vm.onDockStateChanged(pane.DockState);
      }
}

And in your view model you now have a custom function called when the user changes the dock stage.

MyDockPaneViewModel.cs

internal void onDockStateChanged(DockPaneState dockState)
{
if (dockState == DockPaneState.Hidden)
    {
        Console.WriteLine("hidden"); // user clicked the X!
    }
}

 

0 Kudos