Select to view content in your preferred language

Using Itemscontrol and dataBinding

2402
5
03-30-2012 12:43 AM
JasonWard1
Emerging Contributor
Hi - I use MVVM model and am having trouble changing an app from using the Microsoft Bing Map control over to ArcGIS silverlight map control.

The problem lies in that I use the MapItemsControl property from Bing to display buttons on a map using a template and binding the objects that contain the information I need to build the buttons correctly (they contain images and text and are coloured based on data received).  This all works with the microsoft control - I just need to work out how to do the same thing with ArcGIS.

The problem I am getting is that it appears to fail to bind the ElementLayer.Envelope.  I am using ItemsControl and a local resource template.

I dont seem to be able to find any examples of this - so wonder if I am even on the right path!

Any help would be most appreciated
0 Kudos
5 Replies
JenniferNery
Esri Regular Contributor
ElementLayer.Envelope is an Attached property and therefore support binding. It expects value of type Envelope. You can try the following code:

      xmlns:esri="http://schemas.esri.com/arcgis/client/2009">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.Resources>      
            <esri:Envelope x:Key="MyEnvelope"  XMin="-117" YMin="34" XMax="-117" YMax="34"/>
        </Grid.Resources>
            <esri:Map x:Name="MyMap">
            
            <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" 
                    Url="http://services.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer"/>

            <esri:ElementLayer>
                <esri:ElementLayer.Children>
                    <!--Clickable button-->
                    <Button x:Name="RedlandsButton" Width="20" Height="20" Content="X" 
            esri:ElementLayer.Envelope="{Binding Source={StaticResource MyEnvelope}}"
            VerticalAlignment="Center" HorizontalAlignment="Center"/>
                </esri:ElementLayer.Children>
            </esri:ElementLayer>
        </esri:Map>
    </Grid>
0 Kudos
JasonWard1
Emerging Contributor
ElementLayer.Envelope is an Attached property and therefore support binding. It expects value of type Envelope. You can try the following code:


Thanks for your reply - Let me show you some pseudo code as its a litle more complcated that it sounds (to me anyhow!)

I have simplified things to a border.

        <DataTemplate x:Name="example1">
            <Border BorderBrush="AliceBlue" BorderThickness="2" esri:ElementLayer.Envelope="{Binding _envelope}" Background="AliceBlue" />
        </DataTemplate>

<esri:Map x:Name="Map">
      <esri:ArcGISTiledMapServiceLayer ID="BaseLayer" Url="http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer" />
            <esri:ElementLayer>
                  <esri:ElementLayer.Children>
                       <ItemsControl ItemTemplate="{StaticResource example1}" ItemsSource="{Binding Path=_BordersforDisplay, Mode=OneWay}" />
                  </esri:ElementLayer.Children>                                  
            </esri:ElementLayer>
</esri:Map>



The observable collection _BordersforDisplay is shown simply below without the notification code OnPropertyChanged()


public ObservableCollection<BorderItems> _BordersforDisplay = new ObservableCollection<BorderItems>();

public class BorderItems
{
        public string _name { get; set; }
        public Envelope _envelope { get; set; }
}



As far as I can see, this should work - and I use this same code on a Bing Maps Control using the MapItemsControl in the Map Layer.  Do I need something Similar here?

Thanks again for your help with this.
0 Kudos
JenniferNery
Esri Regular Contributor
ElementLayer.Children is of type ObservableCollection<UIElement>. So in your code, you want just one child ItemsControl? Each child must specify its location through esri:ElementLayer.Envelope. Was your code snippet working for you? Are you getting errors? If you are using Silverlight5, you can debug XAML code and see if the binding statements are resolved.
0 Kudos
JasonWard1
Emerging Contributor
I simplified the code from my source - I havent actually tested it in itself, but the principle is the same.

The ItemsControl source is a number of objects where the property _envelope is bound to the ElementLayer.Envelope in the itemtemplate "example1".

I have used this using the MapItemsControl from Microsoft on a bing map - am now looking to transfer to ArcGIS as a client has an in house server they want to use. 

After a bit more looking at the error, it would appear that rather than the itemscontrol holding a number of objects that get added as children, that the itemcontrol itself is treated as a child of the elementlayer.  Or maybe it doesnt like the ItemTemplate the way I am doing it.  Am a bit confused as to why - is the datatemplate the correct way to do this?

Thanks again for your help 🙂
0 Kudos
JenniferNery
Esri Regular Contributor
If you want to bind to ElementLayer.Children, I think the following code should work:

     xmlns:local="clr-namespace:Sprint20"
     xmlns:esri="http://schemas.esri.com/arcgis/client/2009">
  
 <Grid x:Name="LayoutRoot" Background="White">
  <Grid.Resources>
   <esri:Envelope x:Key="MyEnvelope"  XMin="-117" YMin="34" XMax="-117" YMax="34"/>
   <local:MyUIElements x:Key="MyElementLayerChildren">
    <!--Clickable button-->
    <Button x:Name="RedlandsButton" Width="20" Height="20" Content="X" 
            esri:ElementLayer.Envelope="{StaticResource MyEnvelope}"
            VerticalAlignment="Center" HorizontalAlignment="Center" />

    <!--Arrow pointing at Copenhagen from the right-->
    <TextBlock Text="&lt;=" HorizontalAlignment="Right" 
         FontSize="15" Foreground="Blue" FontWeight="Bold"
         esri:ElementLayer.Envelope="12.5698,55.6765,12.5698,55.6765" />
    <!--Arrow pointing at Copenhagen from the left-->
    <TextBlock Text="=&gt;" HorizontalAlignment="Left" 
         FontSize="15" Foreground="Blue" FontWeight="Bold"
         esri:ElementLayer.Envelope="12.5698,55.6765,12.5698,55.6765" />

    <!-- Red box - No size specified. Envelope guides the size -->
    <Rectangle Fill="Red" esri:ElementLayer.Envelope="0,0,10,10" />

    <!--Editable textbox-->
    <TextBox Width="100" Height="20" esri:ElementLayer.Envelope="40,0,40,0"
       Text="Editable text" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
   </local:MyUIElements>
  </Grid.Resources>
   <esri:Map x:Name="MyMap">
   <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" 
                    Url="http://services.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer"/>

   <esri:ElementLayer Children="{Binding Source={StaticResource MyElementLayerChildren}}"/>

  </esri:Map>

 </Grid>


This local class will allow you to create an instance of ObservableCollection type.
 public class MyUIElements : ObservableCollection<UIElement>
 {
  public MyUIElements() { }
 }
0 Kudos