Select to view content in your preferred language

How to binding mainpage's map?

2352
16
10-27-2010 05:54 AM
ShaningYu
Honored Contributor
Title should be How to bind to MainPage's map?
---------------------------------

This is the continuation of the thread: http://forums.arcgis.com/threads/15556-ClosedFacility?p=49147#post49147.  The scenario is described below:
1) Create a UserControls file by loading the ClosedFacility component from ESRI: http://help.arcgis.com/en/webapi/sil...losestFacility
2) In the usercontrol xaml, I defined
            <esri:Map x:Name="_Map" Background="White" Extent="-117.23,34.03,-117.16,34.08" >
3) Add some code in MainPage.xaml and MainPage.xaml.cs to load the ClosedFacility dialog when it is needed. Also set this component's _Map is set to the same as the parent's map.
Results obtained:  All of the buttons are disabled.

I reported this incident.  ESRI's Jennifer responded me that:
"All the buttons have Command binding which can only be resolved if their DataContext is resolved. In this sample, each button's DataContext is set to an Editor which is part of Resources. Each of these editors has their Map property bound to a map, using Element binding.
Since you are moving this to a different UserControl that does not contain your map, Element binding will not work. You need to resort to other means of binding. Maybe create your own DependencyProperty (Map) in the UserControl so that you can use this instead. "

Per her advise, I revised the code (only 1 line here) in the usercontrol's xaml:
                <esri:Editor x:Key="MyBarriersEditor" LayerIDs="MyBarriersGraphicsLayer"
                         Map="{Binding ElementName=_Map}" />
to:
                <esri:Editor x:Key="MyBarriersEditor" LayerIDs="MyBarriersGraphicsLayer"
                         Map="{Binding ElementName=MainPage.MyMap}" />
But it still does not work.  I believe that the binding is not right.  It is somehow chanllege for me and I have very limited experience on it.  Do you know how to bind the usercontrol's map to the MainPage's map?  Thanks.
0 Kudos
16 Replies
JenniferNery
Esri Regular Contributor

<esri:Editor x:Key="MyBarriersEditor" LayerIDs="MyBarriersGraphicsLayer"
Map="{Binding ElementName=_Map}" />


Is _Map an element of this UserControl? If not, that's the reason the element binding failed. If you want to use this type of binding, your UserControl should have had something like
<esri:Map x:Name="_Map" .../>

I suggested to make Map a DependencyProperty in your UserControl so that in your MainPage you can do something like:
<local:ClosestFacilityControl Map="{Binding ElementName=MyMap}" VerticalAlignment="Top" HorizontalAlignment="Center"/>


Your UserControl will need to set Map of each editor a different way. Also, you will not be able to get layers this way (since MyMap does not exist).
            facilitiesGraphicsLayer = MyMap.Layers["MyFacilitiesGraphicsLayer"] as GraphicsLayer;

  public Map Map
  {
   get { return GetValue(MapProperty) as Map; }
   set { SetValue(MapProperty, value); }
  }

  public static readonly DependencyProperty MapProperty = DependencyProperty.Register("Map",
     typeof(Map), typeof(ClosestFacilityControl), new PropertyMetadata(OnMapPropertyChanged));

  private static void OnMapPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
   ClosestFacilityControl control = d as ClosestFacilityControl;
   Map newMap = e.NewValue as Map;
   if(control!=null)
   {
    Editor editor = control.LayoutRoot.Resources["MyBarriersEditor"] as Editor;
    if(editor!=null)
     editor.Map = newMap;
    editor = control.LayoutRoot.Resources["MyFacilitiesEditor"] as Editor;
    if(editor!=null)
     editor.Map = newMap;
    editor = control.LayoutRoot.Resources["MyIncidentsEditor"] as Editor;
    if(editor!=null)
     editor.Map = newMap;

    control.facilitiesGraphicsLayer = newMap.Layers["MyFacilitiesGraphicsLayer"] as GraphicsLayer;
    control.IncidentsGraphicsLayer = newMap.Layers["MyIncidentsGraphicsLayer"] as GraphicsLayer;
    control.barriersGraphicsLayer = newMap.Layers["MyBarriersGraphicsLayer"] as GraphicsLayer;
    control.routeGraphicsLayer = newMap.Layers["MyRoutesGraphicsLayer"] as GraphicsLayer;
   }
  }


Also, you need not create a new thread if it's the same issue 😛
0 Kudos
ShaningYu
Honored Contributor
Jennifer:
Thanks for your response.  Per your advise, I am trying to fix the problem step by step.
First of all, in the MainPage, the code was revised as:
            <local:ClosetFacilityControl x:Name="MyClosedFacility" Visibility="Collapsed"
                             Height="240" Width="440" Canvas.Left="306" Canvas.Top="140"
                             DataContext="{Binding ElementName=MyMap}"
                             _Map="{Binding ElementName=MyMap}"  />
However, I received the error that:
   the property '_Map' does not exist on the type 'ClosetFacilityControl' in the XML neamspace ...
Actually, in my ClosetFacilityContro.xaml, the '_Map' is defined like that:
<Grid x:Name="LocalPanel" Style="{StaticResource DialogBaseItemsGrid}">
   <esri:Map x:Name="_Map" Background="White" Extent="-117.23,34.03,-117.16,34.08" >
      ....
   </esri:Map>

Please point out what is wrong about my coding.  Many thanks.
0 Kudos
DominiqueBroux
Esri Frequent Contributor
You have to create a dependency property by code.

You can use the code that Jennifer gave:

 
 public Map Map
{
get { return GetValue(MapProperty) as Map; }
set { SetValue(MapProperty, value); }
}
 
public static readonly DependencyProperty MapProperty = DependencyProperty.Register("Map",
  typeof(Map), typeof(ClosestFacilityControl), new PropertyMetadata(OnMapPropertyChanged));
.......
 
 


With your xaml code:
<esri:Map x:Name="_Map" Background="White" Extent="-117.23,34.03,-117.16,34.08" >
....
</esri:Map>

you are creating a new map but not a property which can be set to a map.
0 Kudos
ShaningYu
Honored Contributor
In the Usercontrol's xaml, several GraphicsLayers are defined in the map, like that:
            <esri:Map x:Name="_Map" Background="White" Extent="-117.23,34.03,-117.16,34.08"     >
                <!--<esri:ArcGISTiledMapServiceLayer
                      Url="http://services.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>-->

                <esri:GraphicsLayer ID="MyRoutesGraphicsLayer" Renderer="{StaticResource RouteRenderer}" >
                    <esri:GraphicsLayer.MapTip>
                        <Border CornerRadius="10" Background="#DDFFEEEE" BorderThickness="5" BorderBrush="#7700FF00">
                            <StackPanel Orientation="Vertical" HorizontalAlignment="Center" Margin="10">
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="From Incident " FontWeight="Bold" Foreground="#FF0F274E" FontSize="10" VerticalAlignment="Center"/>
                                    <TextBlock Text="{Binding [IncidentID]}" HorizontalAlignment="Left" VerticalAlignment="Center" />
                                </StackPanel>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="To Facility " FontWeight="Bold" Foreground="#FF0F274E" FontSize="10" VerticalAlignment="Center"/>
                                    <TextBlock Text="{Binding [FacilityID]}" HorizontalAlignment="Left" VerticalAlignment="Center" />
                                </StackPanel>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="Total Time (mins): " FontWeight="Bold" Foreground="#FF0F274E" FontSize="10" VerticalAlignment="Center" />
                                    <TextBlock Text="{Binding [Total_Time], StringFormat=\{0:F\}}" HorizontalAlignment="Left" VerticalAlignment="Center" />
                                </StackPanel>
                            </StackPanel>
                        </Border>
                    </esri:GraphicsLayer.MapTip>
                </esri:GraphicsLayer>

                <esri:GraphicsLayer ID="MyIncidentsGraphicsLayer" />
                <esri:GraphicsLayer ID="MyBarriersGraphicsLayer" />
                <esri:GraphicsLayer ID="MyFacilitiesGraphicsLayer" />
            </esri:Map>
Per your post, I should remove this piece of code and then use
public Map Map {
   ...
}
Is it right?  If so, how can I define these graphicslayers?  Thanks.
0 Kudos
DominiqueBroux
Esri Frequent Contributor
Per your post, I should remove this piece of code and then use
public Map Map {
...
}
Is it right? If so, how can I define these graphicslayers? Thanks.


No, sorry I was not clear enough. You can keep the definition of your map and its layer in XAML but you have to bind the map property of your control to this map defined in XAML.

 
<local:ClosestFacilityControl x:Name="MyClosedFacility" Visibility="Collapsed"
Height="240" Width="440" Canvas.Left="306" Canvas.Top="140"
Map="{Binding ElementName=_Map}" />


'Map' being the name of your dependency property defined by code
and '_Map' the name of your map defined in XAML
0 Kudos
ShaningYu
Honored Contributor
Thanks for your clarification.  I loaded the code
public Map Map {
  ...
}
into my usercontrol class: ClosestFacilityControl.
but received another error for the 'ClosestFacilityControl', which is the same as my usercontrol's name.  The error message shows that
The type or namespace name 'ClosestFacilityControl' could not be found. (are you missing a using directive or an assembly reference?)
Whatdoes it mean?  Thanks.
0 Kudos
JenniferNery
Esri Regular Contributor
Did you add the namespace in xaml?

xmlns:local="clr-namespace:YourUserControlNamespace">

and added UserControl this way?

<local:ClosestFacilityControl ../>
0 Kudos
ShaningYu
Honored Contributor
Tat problem was solved but the buttons are still grayed out.  I put a stop point at
public Map Map {   }
and then run debugging.  However, this method is not called at all.  I believe there should be a call somewhere that I haven't specify.  Please tell me how to call the method.  Many thanks.
0 Kudos
JenniferNery
Esri Regular Contributor
If you have properly defined the DependencyProperty in your ClosestFacilityControl, and have set Map property when you instantiated an instance of this control in your MainPage, you can set breakpoint at OnMapPropertyChanged and it should be hit.

Also in your ClosestFacilityControl, did you remove the element binding to map for the editors?
 
       <esri:Editor x:Key="MyBarriersEditor" LayerIDs="MyBarriersGraphicsLayer" Map="{Binding ElementName=MyMap}" />

This should be removed since the OnMapPropertyChanged will handle setting the editor's Map property.
0 Kudos