Select to view content in your preferred language

identifyTask w/fieldsToDisplay not showing multi features

441
4
07-27-2012 02:09 AM
JohnWall
Regular Contributor
I have started with the identify sample code and modified it to show specific fields for a FeatureLayer. However, now I am having issues getting features, which are close to one another or on top of one another, to be returned by the identifyTask and selectable within the Grid.

I believe it has something to do with the
void cb_SelectionChanged
code referencing .Data instead of something else, but I am not sure.

Here is a XAML snippet:
<ComboBox x:Name="IdentifyComboBox" SelectionChanged="cb_SelectionChanged"
                         Margin="5,1,5,5" Grid.Row="0">
                    </ComboBox>


Here is the C# snippet:
public void ShowFeatures(List<IdentifyResult> results)
        {
            _dataItems = new List<DataItem>();

            if (results != null && results.Count > 0)
            {
                IdentifyComboBox.Items.Clear();
                foreach (IdentifyResult result in results)
                {
                    Graphic feature = result.Feature;
                    string title = result.Value.ToString() + " (" + result.LayerName + ")";
                    _dataItems.Add(new DataItem()
                    {
                        Title = title,
                        Data = feature.Attributes
                    });
                    var fieldsToDisplay = new List<string>() { "OBJECTID", "Projekt", "Laufzeit", "Ansprechpa" };
                    var attributesToDisplay = new Dictionary<string, object>();
                    foreach (var item in feature.Attributes)
                        if(fieldsToDisplay.Contains(item.Key))
                            attributesToDisplay[item.Key]= item.Value;
                    IdentifyDetailsDataGrid.ItemsSource = attributesToDisplay;
                }
                IdentifyComboBox.SelectedIndex = 0;
            }
        }

        void cb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int index = IdentifyComboBox.SelectedIndex;
            if (index > -1)
                IdentifyDetailsDataGrid.ItemsSource = _dataItems[index].Data;
        }
0 Kudos
4 Replies
JohnWall
Regular Contributor
Can anyone help me out? Please
0 Kudos
DominiqueBroux
Esri Frequent Contributor
foreach (IdentifyResult result in results)
{
Graphic feature = result.Feature;
string title = result.Value.ToString() + " (" + result.LayerName + ")";
_dataItems.Add(new DataItem()
{
Title = title,
Data = feature.Attributes
});
var fieldsToDisplay = new List<string>() { "OBJECTID", "Projekt", "Laufzeit", "Ansprechpa" };
var attributesToDisplay = new Dictionary<string, object>();
foreach (var item in feature.Attributes)
if(fieldsToDisplay.Contains(item.Key))
attributesToDisplay[item.Key]= item.Value;
IdentifyDetailsDataGrid.ItemsSource = attributesToDisplay;
}


Looks like you initialize IdentifyDetailsDataGrid.ItemsSource in the loop so each dictionary with the attributes to display is overwriting the previous one.

I think you have to store attributesToDisplay in your DataItem class and to reuse it to set ItemsSource in the SelectionChanged event.
0 Kudos
JohnWall
Regular Contributor
Looks like you initialize IdentifyDetailsDataGrid.ItemsSource in the loop so each dictionary with the attributes to display is overwriting the previous one.

I think you have to store attributesToDisplay in your DataItem class and to reuse it to set ItemsSource in the SelectionChanged event.


Thank you for your reply. Sorry to ask such questions, but I am new to Silverlight and have been asked to test out all of the APIs.

I understand now see that I am initializing IdentifyDetailsDataGrid.ItemsSource in the loop, but I am uncertain how to store attributesToDisplay in DataItem and then reuse it to set ItemsSource in the SelectionChanged event. Previously, I found this forum posting which got me to the point I am at right now. I have tried finding a resource on storing data in classes, but have been unsuccessful. My C# code look as follows (although I now understand I need to remove IdentifyDetailsDataGrid.ItemsSource = attributesToDisplay;😞

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Tasks;

namespace identify
{
    public partial class MainPage : UserControl
    {
        private List<DataItem> _dataItems = null;

        public MainPage()
        {
            InitializeComponent();
        }

        private void QueryPoint_MouseClick(object sender, ESRI.ArcGIS.Client.Map.MouseEventArgs e)
        {
            ESRI.ArcGIS.Client.Geometry.MapPoint clickPoint = e.MapPoint;

            ESRI.ArcGIS.Client.Tasks.IdentifyParameters identifyParams = new IdentifyParameters()
            {
                Geometry = clickPoint,
                MapExtent = MyMap.Extent,
                Width = (int)MyMap.ActualWidth,
                Height = (int)MyMap.ActualHeight,
                LayerOption = LayerOption.visible,
                SpatialReference = MyMap.SpatialReference
            };

            IdentifyTask identifyTask = new IdentifyTask("http://<someServer>/ArcGIS/rest/services/test/MapServer");
            identifyTask.ExecuteCompleted += IdentifyTask_ExecuteCompleted;
            identifyTask.Failed += IdentifyTask_Failed;
            identifyTask.ExecuteAsync(identifyParams);
        }

        public void ShowFeatures(List<IdentifyResult> results)
        {
            _dataItems = new List<DataItem>();

            if (results != null && results.Count > 0)
            {
                IdentifyComboBox.Items.Clear();
                foreach (IdentifyResult result in results)
                {
                    Graphic feature = result.Feature;
                    string title = result.Value.ToString() + " (" + result.LayerName + ")";
                    _dataItems.Add(new DataItem()
                    {
                        Title = title,
                        Data = feature.Attributes
                    });
                    var fieldsToDisplay = new List<string>() { "OBJECTID", "Projekt", "Laufzeit", "Ansprechpa" };
                    var attributesToDisplay = new Dictionary<string, object>();
                    foreach (var item in feature.Attributes)
                        if(fieldsToDisplay.Contains(item.Key))
                            attributesToDisplay[item.Key]= item.Value;
                    IdentifyDetailsDataGrid.ItemsSource = attributesToDisplay;
                }
                IdentifyComboBox.SelectedIndex = 0;
            }
        }

        void cb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int index = IdentifyComboBox.SelectedIndex;
            if (index > -1)
                IdentifyDetailsDataGrid.ItemsSource = _dataItems[index].Data;
        }

        private void IdentifyTask_ExecuteCompleted(object sender, IdentifyEventArgs args)
        {
            IdentifyDetailsDataGrid.ItemsSource = null;

            if (args.IdentifyResults != null && args.IdentifyResults.Count > 0)
            {
                IdentifyResultsPanel.Visibility = Visibility.Visible;

                ShowFeatures(args.IdentifyResults);
            }
            else
            {
                IdentifyComboBox.Items.Clear();
                IdentifyComboBox.UpdateLayout();

                IdentifyResultsPanel.Visibility = Visibility.Collapsed;
            }
        }

        public class DataItem
        {
            public string Title { get; set; }
            public IDictionary<string, object> Data { get; set; }
        }

        void IdentifyTask_Failed(object sender, TaskFailedEventArgs e)
        {
            MessageBox.Show("Identify failed. Error: " + e.Error);
        }

    }
}
0 Kudos
DominiqueBroux
Esri Frequent Contributor
You can use the Data member to store the attributesToDisplay.

Something like:

 
                var fieldsToDisplay = new List<string>() { "OBJECTID", "Projekt", "Laufzeit", "Ansprechpa" };
                foreach (IdentifyResult result in results)
                {
                    Graphic feature = result.Feature;
                    string title = result.Value.ToString() + " (" + result.LayerName + ")";
                    var attributesToDisplay = new Dictionary<string, object>();
                    foreach (var item in feature.Attributes)
                      if(fieldsToDisplay.Contains(item.Key))
                        attributesToDisplay[item.Key]= item.Value;

                    _dataItems.Add(new DataItem()
                    {
                        Title = title,
                        Data = attributesToDisplay 
                    });
                }
0 Kudos