Update control on DockPane

2403
5
Jump to solution
08-04-2017 12:10 PM
BrianBulla
Occasional Contributor III

Following the BingStreetside sample on GitHub, I have created a MapTool and a DockPane.  On the DockPaneI have a WebBroswer control that I want to update when I click on the map with the MapTool.  I am having troubles referencing the DockPanel from the MapTools click event.

Here is a snippet of the Dockpane.xaml for the WebBrowser:

<Grid Margin="0">
<WebBrowser x:Name="streetViewControl" Margin="0" />
</Grid>

Here is the code I am using in Dockpane.xaml.cs:

namespace StreetView_ArcPro
{
/// <summary>
/// Interaction logic for DockpaneView.xaml
/// </summary>
public partial class DockpaneView : UserControl //public partial
{
public DockpaneView()
{
InitializeComponent();
streetViewControl.Navigated += StreetViewControl_Navigated;
streetViewControl.Navigate("http://maps.google.ca");
}

public void SetMapLocation(double lng, double lat)
{
streetViewControl.Navigate(@"http://maps.google.ca/maps?q=" + lat + "," + lng + "&num1&s11=" + lat + "," + lng + "&sspn=16.71875,56.536561&ie=UTF8&ll=" + lat + "," + lng + "&spn=0.020401,0.028753&z=15&layer=c&cbll=" + lat + "," + lng + "&panoid=&cbp=12,161.92,,0,5");
}

private void StreetViewControl_Navigated(object sender, NavigationEventArgs e)
{
MessageBox.Show("Navigated");
}
}
}

And here is the code for the MapTool.  See comments for where I am running into problems:

namespace StreetView_ArcPro
{
public class StreetView_Tool : MapTool
{
public StreetView_Tool()
{
IsSketchTool = true;
SketchType = SketchGeometryType.Point;
SketchOutputMode = SketchOutputMode.Map;
}

protected override Task OnToolActivateAsync(bool active)
{
return base.OnToolActivateAsync(active);
}

protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
{
double lat;
double lng;

var coord = GeometryEngine.Instance.Project(geometry, SpatialReferences.WGS84) as MapPoint;
if (coord != null)
{
lng = coord.X;
lat = coord.Y;


//**********This is where I want to call the SetMapLocation on the DockPane, but I have no idea how to do it***********

//**********This next two line do not give me errors, but it just doesn't work.*******

var sample = new DockpaneView();
sample.SetMapLocation(lng, lat);


}

var ret = QueuedTask.Run(() =>
{
return true;
}
);

return ret;

//return base.OnSketchCompleteAsync(geometry);
}

}
}

Any assistance is appreciated.

Thanks!

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
Wolf
by Esri Regular Contributor
Esri Regular Contributor

DockPanes are implemented using MVVM meaning that the business (or code-behind) logic is defined in the 'DockPane1ViewModel' class and the UI is defined in the 'DockPane1View' class.  I think your code snippet above is confusing View and ViewModel.

To get a reference for a 'test' method that I defined in my DockPane1ViewModel class I can use this snippet:

DockPane pane = FrameworkApplication.DockPaneManager.Find("ProAppModule15_Dockpane1");
if (pane == null) return;
// Cast to my specific implementation
Dockpane1ViewModel panevm = pane as Dockpane1ViewModel;
if (panevm != null) MessageBox.Show(panevm.test());

However, if you want to get a handle to your VIEW (i.e. in my case this is the DockPaneView1 class), then you need to implement your own access method in your DockPaneView1 class.  Remember that dockpanes are always singletons in ArcGIS Pro so there is always only one instance of your view at a time.  Here is sample of an access method that allows me to reference my View class 'DockPane1View':

    public partial class Dockpane1View : UserControl
    {
        public Dockpane1View()
        {
            InitializeComponent();
            // set _this property here:
            _this = this;
        }
        private static Dockpane1View _this = null;
        // static method to get reference to my DockpaneView instance
        static public Dockpane1View MyDockpaneView => _this;
        // sample method
        public string test ()
        { return "test1"; }
    }

Now I can call the 'test' method above from anywhere like this:

Dockpane1View myView = Dockpane1View.MyDockpaneView;
MessageBox.Show (myView.test());

View solution in original post

5 Replies
Wolf
by Esri Regular Contributor
Esri Regular Contributor

Hi Brian,

 In order to show a Dockpane you have to add the Dockpane to the config.daml first.  I would use the 'Dockpane Item Template' to do this to make sure that all your code is stubbed out properly.  Once you do this you can see the Dockpane definition in your config.daml:

<dockPanes>
   <dockPane id="ProAppModule15_Dockpane1" caption="Dockpane 1" className="Dockpane1ViewModel" dock="group" dockWith="esri_core_contentsDockPane">
      <content className="Dockpane1View" />
   </dockPane>
</dockPanes>

There is also a button to show the Dockpane, but you can remove the button later after you show the Dockpane from your add-in's MapTool.  To show the code from within your MapTool you can simply use the code snippet from that button's OnClick method:

// the Show method is static can automatically stubbed out
// so you can call Show directly from your add-in code:

Dockpane1ViewModel.Show();

or you can copy the activation code from the Show method and create your 'own' show method (this will work even if your MapTool is in a separate add-in component):

// this is the ID from the dockpane definition in the config.daml file
string _dockPaneID = "ProAppModule15_Dockpane1";

DockPane pane = FrameworkApplication.DockPaneManager.Find(_dockPaneID);
if (pane == null) return;
pane.Activate();
0 Kudos
BrianBulla
Occasional Contributor III

Hi Wolfgang,

Yes, I have the DockPane added already, and I can see the initial URL ("http://maps.google.ca") appear in the WebBrowser control.

My problem is that I cannot get the control to update with a new URL once I click on the map.  I'm not sure if am referencing the DockPane properly in order to update the control that is on it.

I am trying this now, but still with no luck.

DockPane paneIT = FrameworkApplication.DockPaneManager.Find("StreetView_ArcPro_Dockpane");
DockpaneView pane = paneIT;
pane.SetMapLocation(lng, lat);

It's basically a guessing game for me at this point.

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

DockPanes are implemented using MVVM meaning that the business (or code-behind) logic is defined in the 'DockPane1ViewModel' class and the UI is defined in the 'DockPane1View' class.  I think your code snippet above is confusing View and ViewModel.

To get a reference for a 'test' method that I defined in my DockPane1ViewModel class I can use this snippet:

DockPane pane = FrameworkApplication.DockPaneManager.Find("ProAppModule15_Dockpane1");
if (pane == null) return;
// Cast to my specific implementation
Dockpane1ViewModel panevm = pane as Dockpane1ViewModel;
if (panevm != null) MessageBox.Show(panevm.test());

However, if you want to get a handle to your VIEW (i.e. in my case this is the DockPaneView1 class), then you need to implement your own access method in your DockPaneView1 class.  Remember that dockpanes are always singletons in ArcGIS Pro so there is always only one instance of your view at a time.  Here is sample of an access method that allows me to reference my View class 'DockPane1View':

    public partial class Dockpane1View : UserControl
    {
        public Dockpane1View()
        {
            InitializeComponent();
            // set _this property here:
            _this = this;
        }
        private static Dockpane1View _this = null;
        // static method to get reference to my DockpaneView instance
        static public Dockpane1View MyDockpaneView => _this;
        // sample method
        public string test ()
        { return "test1"; }
    }

Now I can call the 'test' method above from anywhere like this:

Dockpane1View myView = Dockpane1View.MyDockpaneView;
MessageBox.Show (myView.test());
BrianBulla
Occasional Contributor III

Thanks for the help.  I'm a bit confused by your explanation of DockpaneView and DockpaneViewModel, but I'm trying to work with what you have posted.  Things are definitely closer to working.  I had some troubles getting your code to work, but once I added the _this = this; in the DockpaneView:UserControl I was good.

I no longer get errors, but the WebControl is not refreshing with the new URL based on the Lat/Long of the mouse click.

0 Kudos
BrianBulla
Occasional Contributor III

Hmmmm.....and it seems like the WebBrowser control is not capable of handling Google Streetview.  I can get it to Navigate to other pages, but a link to Google Streetview causes nothing but problems.

Oh well....at least I know how a DockPane works now!!

0 Kudos