protected virtual void WriteBaseElementContents(Layer layer)
        {
            // Write extended layer properties
            bool isBaseMapLayer = (bool)layer.GetValue(ESRI.ArcGIS.Client.WebMap.Document.IsBaseMapProperty);

            if (isBaseMapLayer)
            {
                writer.WriteElementString(Constants.esriExtensibilityPrefix, "Document.IsBaseMap", Constants.esriExtensibilityNamespace, "true");
            }
            if (LayerExtensions.GetIsReferenceLayer(layer))
            {
                writer.WriteElementString(Constants.esriMappingPrefix, "LayerExtensions.IsReferenceLayer", Constants.esriMappingNamespace, "true");
            }

            if (LayerExtensions.GetUsesProxy(layer))
            {
                writer.WriteElementString(Constants.esriMappingPrefix, "LayerExtensions.UsesProxy", Constants.esriMappingNamespace, "true");
            }

            string displayName = layer.GetValue(ESRI.ArcGIS.Client.Extensibility.MapApplication.LayerNameProperty) as string;

            if (!string.IsNullOrEmpty(displayName))
            {
                writer.WriteElementString(Constants.esriMappingPrefix, "LayerExtensions.LayerName", Constants.esriMappingNamespace, displayName);
            }

            string displayUrl = (string)layer.GetValue(LayerExtensions.DisplayUrlProperty);

            if (!string.IsNullOrEmpty(displayUrl))
            {
                writer.WriteElementString(Constants.esriMappingPrefix, "LayerExtensions.DisplayUrl", Constants.esriMappingNamespace, displayUrl);
            }
            // Auto-Update is only available for certain layer types
            if (layer is FeatureLayer || layer is ArcGISDynamicMapServiceLayer || layer is CustomGraphicsLayer)
            {
                double autoUpdateInterval = LayerExtensions.GetAutoUpdateInterval(layer);
                // We only store the Interval value if it is > 0.  The Interval indicates
                // if auto update is being used.  A value of <=0 means we are not using
                // auto update.
                if (autoUpdateInterval > 0.0d)
                {
                    writer.WriteElementString(Constants.esriMappingPrefix, "LayerExtensions.AutoUpdateInterval",
                                              Constants.esriMappingNamespace, autoUpdateInterval.ToString());
                }
                if (LayerExtensions.GetAutoUpdateOnExtentChanged(layer))
                {
                    writer.WriteElementString(Constants.esriMappingPrefix, "LayerExtensions.AutoUpdateOnExtentChanged", Constants.esriMappingNamespace, "True");
                }
            }
            Collection <int> identifyLayerIds = LayerExtensions.GetIdentifyLayerIds(layer);

            if (identifyLayerIds != null && identifyLayerIds.Count > 0)
            {
                writer.WriteStartElement(Constants.esriMappingPrefix, "LayerExtensions.IdentifyLayerIds", Constants.esriMappingNamespace);
                foreach (int id in identifyLayerIds)
                {
                    writer.WriteStartElement(Constants.sysPrefix, "Int32", Constants.sysNamespace);
                    writer.WriteValue(id);
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }

            Collection <LayerInformation> layerInfos = LayerExtensions.GetLayerInfos(layer);

            if (layerInfos != null)
            {
                writer.WriteStartElement(Constants.esriMappingPrefix, "LayerExtensions.LayerInfos", Constants.esriMappingNamespace);
                LayerInformation.WriteLayerInfos(layerInfos, writer);
                writer.WriteEndElement();
            }

            bool usePopupFromWebMap = LayerExtensions.GetUsePopupFromWebMap(layer);

            if (usePopupFromWebMap)
            {
                writer.WriteElementString(Constants.esriMappingPrefix, "LayerExtensions.UsePopupFromWebMap", Constants.esriMappingNamespace, "true");
            }

            string popupDataTemplates = LayerExtensions.GetSerializedPopupDataTemplates(layer);

            if (!string.IsNullOrEmpty(popupDataTemplates))
            {
                writer.WriteElementString(Constants.esriMappingPrefix, "LayerExtensions.SerializedPopupDataTemplates", Constants.esriMappingNamespace, popupDataTemplates);
            }

            string popupTitles = LayerExtensions.GetSerializedPopupTitleExpressions(layer);

            if (!string.IsNullOrEmpty(popupTitles))
            {
                writer.WriteElementString(Constants.esriMappingPrefix, "LayerExtensions.SerializedPopupTitleExpressions", Constants.esriMappingNamespace, popupTitles);
            }

            popupDataTemplates = LayerExtensions.GetSerializedWebMapPopupDataTemplates(layer);
            if (!string.IsNullOrEmpty(popupDataTemplates))
            {
                writer.WriteElementString(Constants.esriMappingPrefix, "LayerExtensions.SerializedWebMapPopupDataTemplates", Constants.esriMappingNamespace, popupDataTemplates);
            }

            popupTitles = LayerExtensions.GetSerializedWebMapPopupTitleExpressions(layer);
            if (!string.IsNullOrEmpty(popupTitles))
            {
                writer.WriteElementString(Constants.esriMappingPrefix, "LayerExtensions.SerializedWebMapPopupTitleExpressions", Constants.esriMappingNamespace, popupTitles);
            }

            bool isPopupEnabled = ESRI.ArcGIS.Client.Extensibility.LayerProperties.GetIsPopupEnabled(layer);

            if (isPopupEnabled)
            {
                writer.WriteElementString(Constants.esriExtensibilityPrefix, "LayerProperties.IsPopupEnabled", Constants.esriExtensibilityNamespace, "true");
            }
            else
            {
                writer.WriteElementString(Constants.esriExtensibilityPrefix, "LayerProperties.IsPopupEnabled", Constants.esriExtensibilityNamespace, "false");
            }

            if (ESRI.ArcGIS.Client.Extensibility.LayerProperties.GetIsVisibleInMapContents(layer))
            {
                writer.WriteElementString(Constants.esriExtensibilityPrefix, "LayerProperties.IsVisibleInMapContents", Constants.esriExtensibilityNamespace, "true");
            }
            else
            {
                writer.WriteElementString(Constants.esriExtensibilityPrefix, "LayerProperties.IsVisibleInMapContents", Constants.esriExtensibilityNamespace, "false");
            }
        }
        public static void GetTitle(PopupItem popupItem, LayerInformation info)
        {
            if (popupItem == null)
                return;

            string titleExpression = string.Empty;
            string title = string.Empty;
            
            Layer layer = popupItem.Layer;

            #region Get from developer override/webmap override
            //First get from developer override
            IDictionary<int, string> titleExpressions = ESRI.ArcGIS.Client.Extensibility.LayerProperties.GetPopupTitleExpressions(layer);
            //then if defined in web map
            if (titleExpressions == null && ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetUsePopupFromWebMap(layer))
                titleExpressions = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetWebMapPopupTitleExpressions(layer);
            if (titleExpressions != null)
            {
                if (layer is GraphicsLayer)
                    titleExpression = (titleExpressions.ContainsKey(-1)) ? titleExpressions[-1] : null;
                else
                    titleExpression = (titleExpressions.ContainsKey(popupItem.LayerId)) ? titleExpressions[popupItem.LayerId] : null;
            }
            #endregion

            #region Get title from expression
            if (!string.IsNullOrWhiteSpace(titleExpression))
                title = ConvertExpressionWithFieldNames(popupItem, titleExpression);
            #endregion

            if (string.IsNullOrWhiteSpace(title))
            {
                if (layer is GraphicsLayer) //get from display field set in layer configuration
                {
                    #region Get from display field - Graphics layer
                    string displayFieldName = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetDisplayField(layer as GraphicsLayer);
                    if (!string.IsNullOrWhiteSpace(displayFieldName))
                    {
                        object o = GetFieldValue(popupItem, displayFieldName);
                        title = (o != null) ? o.ToString() : string.Empty;
                        if (string.IsNullOrWhiteSpace(popupItem.TitleExpression))
                            titleExpression = "{" + displayFieldName + "}";
                    }
                    #endregion
                }
                else if (!ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetUsePopupFromWebMap(layer))
                {
                    #region Get from display field - dynamic layer
                    if (!string.IsNullOrEmpty(info.DisplayField))//get from display field set in layer configuration
                    {
                        object o = GetFieldValue(popupItem, info.DisplayField);
                        title = (o != null) ? o.ToString() : string.Empty;
                        titleExpression = "{" + info.DisplayField + "}";
                    }
                    #endregion
                }
            }

            if (title != null)
                title = title.Trim();
            popupItem.Title = title;
            popupItem.TitleExpression = titleExpression;
        }
		public static DataTemplate BuildMapTipDataTemplate(PopupItem popupItem, out bool hasContent, LayerInformation layerInfo = null)
		{
			hasContent = false;
            if (popupItem == null || popupItem.Graphic == null || popupItem.Graphic.Attributes == null || popupItem.Layer == null)
                return null;

            Layer layer = popupItem.Layer;
			string popupDataTemplatesXaml = null;
            #region Get from developer override/webmap override
            //First get from developer override
            IDictionary<int, string> templates = ESRI.ArcGIS.Client.Extensibility.LayerProperties.GetPopupDataTemplates(layer);
            //then if defined in web map
            if (templates == null && ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetUsePopupFromWebMap(layer))
                templates = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetWebMapPopupDataTemplates(layer);
            if (templates != null)
            {
                if (layer is GraphicsLayer)
                    popupDataTemplatesXaml = (templates.ContainsKey(-1)) ? templates[-1] : null;
                else
                    popupDataTemplatesXaml = (templates.ContainsKey(layerInfo.ID)) ? templates[layerInfo.ID] : null;
            }
            #endregion

			DataTemplate dt = null;
			StringBuilder sb = new StringBuilder();
            if (!string.IsNullOrEmpty(popupDataTemplatesXaml))
            {
                // Use popup data template xaml.
                hasContent = true;
                sb.Append(popupDataTemplatesXaml);
            }
            else
            {
                sb.Append("<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ");
                sb.Append("xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" ");
                sb.Append("xmlns:mapping=\"http://schemas.esri.com/arcgis/mapping/2009\" ");
                sb.Append("xmlns:local=\"clr-namespace:ESRI.ArcGIS.Mapping.Controls;assembly=ESRI.ArcGIS.Mapping.Controls\" >");
                sb.Append("<Grid HorizontalAlignment=\"Stretch\"><Grid.Resources>");
                sb.Append("<mapping:LabelAttributeConverter x:Key=\"LabelAttributeConverter\" />");
                sb.Append("<mapping:UrlLocationAttributeConverter x:Key=\"UrlLocationAttributeConverter\" />");
                sb.Append("<mapping:UrlDescriptionAttributeConverter x:Key=\"UrlDescriptionAttributeConverter\" />");
                sb.Append("</Grid.Resources>");

                if (popupItem.FieldInfos != null)
                {
                    // Grid with three columns:
                    sb.Append("<Grid.ColumnDefinitions>");
                    sb.Append("<ColumnDefinition Width=\"2*\"/>");
                    sb.Append("<ColumnDefinition Width=\"Auto\"/>");
                    sb.Append("<ColumnDefinition Width=\"3*\" />");
                    sb.Append("</Grid.ColumnDefinitions>");

                    string gridRowDefinitions = string.Empty;
                    StringBuilder content = new StringBuilder();
                    int numRows = 0;
                    foreach (FieldSettings field in popupItem.FieldInfos)
                    {
                        // If field is not to be displayed, skip this field
                        if (!field.VisibleOnMapTip)
                            continue;

                        hasContent = true;
                        gridRowDefinitions += "<RowDefinition Height=\"Auto\" />";
                        numRows++;

                        // Apply alternating row background to every other row
                        if (numRows % 2 == 0)
                        {
                            content.AppendFormat(@"<Rectangle Fill=""{{StaticResource BackgroundTextColorBrush}}""
                                                HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch""
                                                Grid.ColumnSpan=""3"" Grid.Row=""{0}"" Opacity=""0.15"" />", numRows - 1);
                        }

                        if (!string.IsNullOrEmpty(field.DisplayName))
                        {
                            // This is where we will eventually add code that uses an expression to plug in the actual
                            // value for a field name when curly braces are detected (or something).
                            content.AppendFormat(@"<Grid Grid.Row=""{0}""><TextBlock Grid.Column=""0"" Text=""{1}"" 
                                                Margin=""5,2"" Opacity="".6"" VerticalAlignment=""Center"" 
                                                TextWrapping=""Wrap"" /></Grid>",
                                numRows - 1, PopupInfo.SafeXML(field.DisplayName));
                        }

                        // Process this field regardless of value. We need to create a control that has binding so that as
                        // the value changes during editing the control will adapt and display null and not-null values
                        // properly.
                        object o = GetFieldValue(popupItem, field.Name);
                        StringBuilder element = GetFieldValueElement(field, o, numRows - 1);
                        if (element != null)
                        {
                            content.Append(element);
                        }

                        // Column separator
                        content.AppendFormat(@"<Rectangle Fill=""{{StaticResource BackgroundTextColorBrush}}""
                                                HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch""
                                                Grid.Column=""1"" Grid.Row=""{0}"" Opacity=""0.3"" Width=""1""/>", 
                                                numRows - 1);
                    }

                    #region Add Open Item hyperlink
                    if (layer is CustomGraphicsLayer)
                    {
                        ESRI.ArcGIS.Client.Application.Layout.Converters.LocalizationConverter converter = new Client.Application.Layout.Converters.LocalizationConverter();
                        gridRowDefinitions += "<RowDefinition Height=\"Auto\" />";
                        numRows++;
                        content.AppendFormat("<HyperlinkButton Content=\"{0}\" Grid.ColumnSpan=\"2\" Grid.Row=\"{1}\" CommandParameter=\"{{Binding}}\"><HyperlinkButton.Command><local:OpenItemCommand/></HyperlinkButton.Command></HyperlinkButton>",
                            converter.Get("OpenItem"), numRows - 1);
                    }
                    #endregion

                    if (!string.IsNullOrEmpty(gridRowDefinitions))
                        sb.AppendFormat("<Grid.RowDefinitions>{0}</Grid.RowDefinitions>", gridRowDefinitions);
                    sb.Append(content.ToString());
                }
                sb.Append("</Grid></DataTemplate>");
            }
			try
			{
				dt = (DataTemplate)System.Windows.Markup.XamlReader.Load(sb.ToString());
            }
			catch { /* No content */ }

			return dt;
		}
        public static DataTemplate BuildMapTipDataTemplate(PopupItem popupItem, out bool hasContent, LayerInformation layerInfo = null)
        {
            hasContent = false;
            if (popupItem == null || popupItem.Graphic == null || popupItem.Graphic.Attributes == null || popupItem.Layer == null)
            {
                return(null);
            }

            Layer  layer = popupItem.Layer;
            string popupDataTemplatesXaml = null;

            #region Get from developer override/webmap override
            //First get from developer override
            IDictionary <int, string> templates = ESRI.ArcGIS.Client.Extensibility.LayerProperties.GetPopupDataTemplates(layer);
            //then if defined in web map
            if (templates == null && ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetUsePopupFromWebMap(layer))
            {
                templates = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetWebMapPopupDataTemplates(layer);
            }
            if (templates != null)
            {
                if (layer is GraphicsLayer)
                {
                    popupDataTemplatesXaml = (templates.ContainsKey(-1)) ? templates[-1] : null;
                }
                else
                {
                    popupDataTemplatesXaml = (templates.ContainsKey(layerInfo.ID)) ? templates[layerInfo.ID] : null;
                }
            }
            #endregion

            DataTemplate  dt = null;
            StringBuilder sb = new StringBuilder();
            if (!string.IsNullOrEmpty(popupDataTemplatesXaml))
            {
                // Use popup data template xaml.
                hasContent = true;
                sb.Append(popupDataTemplatesXaml);
            }
            else
            {
                sb.Append("<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ");
                sb.Append("xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" ");
                sb.Append("xmlns:mapping=\"http://schemas.esri.com/arcgis/mapping/2009\" ");
                sb.Append("xmlns:local=\"clr-namespace:ESRI.ArcGIS.Mapping.Controls;assembly=ESRI.ArcGIS.Mapping.Controls\" >");
                sb.Append("<Grid HorizontalAlignment=\"Stretch\"><Grid.Resources>");
                sb.Append("<mapping:LabelAttributeConverter x:Key=\"LabelAttributeConverter\" />");
                sb.Append("<mapping:UrlLocationAttributeConverter x:Key=\"UrlLocationAttributeConverter\" />");
                sb.Append("<mapping:UrlDescriptionAttributeConverter x:Key=\"UrlDescriptionAttributeConverter\" />");
                sb.Append("</Grid.Resources>");

                if (popupItem.FieldInfos != null)
                {
                    // Grid with three columns:
                    sb.Append("<Grid.ColumnDefinitions>");
                    sb.Append("<ColumnDefinition Width=\"2*\"/>");
                    sb.Append("<ColumnDefinition Width=\"Auto\"/>");
                    sb.Append("<ColumnDefinition Width=\"3*\" />");
                    sb.Append("</Grid.ColumnDefinitions>");

                    string        gridRowDefinitions = string.Empty;
                    StringBuilder content            = new StringBuilder();
                    int           numRows            = 0;
                    foreach (FieldSettings field in popupItem.FieldInfos)
                    {
                        // If field is not to be displayed, skip this field
                        if (!field.VisibleOnMapTip)
                        {
                            continue;
                        }

                        hasContent          = true;
                        gridRowDefinitions += "<RowDefinition Height=\"Auto\" />";
                        numRows++;

                        // Apply alternating row background to every other row
                        if (numRows % 2 == 0)
                        {
                            content.AppendFormat(@"<Rectangle Fill=""{{StaticResource BackgroundTextColorBrush}}""
                                                HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch""
                                                Grid.ColumnSpan=""3"" Grid.Row=""{0}"" Opacity=""0.15"" />", numRows - 1);
                        }

                        if (!string.IsNullOrEmpty(field.DisplayName))
                        {
                            // This is where we will eventually add code that uses an expression to plug in the actual
                            // value for a field name when curly braces are detected (or something).
                            content.AppendFormat(@"<Grid Grid.Row=""{0}""><TextBlock Grid.Column=""0"" Text=""{1}"" 
                                                Margin=""5,2"" Opacity="".6"" VerticalAlignment=""Center"" 
                                                TextWrapping=""Wrap"" /></Grid>",
                                                 numRows - 1, PopupInfo.SafeXML(field.DisplayName));
                        }

                        // Process this field regardless of value. We need to create a control that has binding so that as
                        // the value changes during editing the control will adapt and display null and not-null values
                        // properly.
                        object        o       = GetFieldValue(popupItem, field.Name);
                        StringBuilder element = GetFieldValueElement(field, o, numRows - 1);
                        if (element != null)
                        {
                            content.Append(element);
                        }

                        // Column separator
                        content.AppendFormat(@"<Rectangle Fill=""{{StaticResource BackgroundTextColorBrush}}""
                                                HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch""
                                                Grid.Column=""1"" Grid.Row=""{0}"" Opacity=""0.3"" Width=""1""/>",
                                             numRows - 1);
                    }

                    #region Add Open Item hyperlink
                    if (layer is CustomGraphicsLayer)
                    {
                        ESRI.ArcGIS.Client.Application.Layout.Converters.LocalizationConverter converter = new Client.Application.Layout.Converters.LocalizationConverter();
                        gridRowDefinitions += "<RowDefinition Height=\"Auto\" />";
                        numRows++;
                        content.AppendFormat("<HyperlinkButton Content=\"{0}\" Grid.ColumnSpan=\"2\" Grid.Row=\"{1}\" CommandParameter=\"{{Binding}}\"><HyperlinkButton.Command><local:OpenItemCommand/></HyperlinkButton.Command></HyperlinkButton>",
                                             converter.Get("OpenItem"), numRows - 1);
                    }
                    #endregion

                    if (!string.IsNullOrEmpty(gridRowDefinitions))
                    {
                        sb.AppendFormat("<Grid.RowDefinitions>{0}</Grid.RowDefinitions>", gridRowDefinitions);
                    }
                    sb.Append(content.ToString());
                }
                sb.Append("</Grid></DataTemplate>");
            }
            try
            {
                dt = (DataTemplate)System.Windows.Markup.XamlReader.Load(sb.ToString());
            }
            catch { /* No content */ }

            return(dt);
        }
        private LayerInformation ToLayerInfo(MetaData.GPParameter param, int id)
        {
            LayerInformation layerInfo = new LayerInformation()
            {
                Name = param.Name,
                ID = id
            };

            MetaData.GPFeatureRecordSetLayer frs = param.DefaultValue as MetaData.GPFeatureRecordSetLayer;

            if (frs != null && frs.Fields != null && frs.Fields.Length > 0)
            {
                foreach (MetaData.Field field in frs.Fields)
                {
                    if (FieldHelper.IsFieldFilteredOut(field.Type))
                        continue;

                    layerInfo.Fields.Add(new ESRI.ArcGIS.Mapping.Core.FieldInfo()
                    {
                        DisplayName = field.Alias,
                        FieldType = mapFieldType(field.Type),
                        Name = field.Name,
                        VisibleInAttributeDisplay = true,
                        VisibleOnMapTip = true,
                    });
                    if (string.IsNullOrEmpty(layerInfo.DisplayField)) layerInfo.DisplayField = field.Name;
                }
            }
            return layerInfo;
        }
        private void processPre10LayerInfoResult(ArcGISWebClient.DownloadStringCompletedEventArgs e)
        {
            #region Parse layer ids from json
            if (e.Cancelled)
                return;
            if (e.Error != null)
            {
                onLayerInfosCompleted(new LayerInfosEventArgs() { LayerInfos = null, UserState = e });
                return;
            }
            string json = null;
            try
            {
                json = e.Result;
            }
            catch (Exception exception)
            {
                if (exception != null)
                {
                    onLayerInfosCompleted(new LayerInfosEventArgs() { LayerInfos = null, UserState = e });
                    return;
                }
            }
            Exception ex = ESRI.ArcGIS.Mapping.DataSources.Utils.CheckJsonForException(json);
            if (ex != null)
            {
                onLayerInfosCompleted(new LayerInfosEventArgs() { LayerInfos = null, UserState = e });
                return;
            }

            MapServiceInfo mapServiceInfo = JsonSerializer.Deserialize<MapServiceInfo>(json);
            if (mapServiceInfo == null || mapServiceInfo.Layers == null)
            {
                onLayerInfosCompleted(new LayerInfosEventArgs() { LayerInfos = null, UserState = e });
                return;
            }
            singleRequestLayerIds = new List<int>();
            foreach (MapServiceLayerInfo layer in mapServiceInfo.Layers)
            {
                LayerInformation info = new LayerInformation()
                {
                    ID = layer.ID,
                    Name = layer.Name,
                    PopUpsEnabled = false
                };
                if (layer.SubLayerIds == null || layer.SubLayerIds.Length < 1)
                {
                    singleRequestLayerIds.Add(layer.ID);
                }
            }
            if (singleRequestLayerIds.Count < 1)
            {
                onLayerInfosCompleted(new LayerInfosEventArgs() { LayerInfos = null, UserState = e });
            }
            else
            {
                singleRequestLayerInfos = new List<LayerInformation>();
                singleRequestWebClients = new List<ArcGISWebClient>();
                cancelSingleRequests = false;
                pendingRequests = singleRequestLayerIds.Count;
                foreach (int id in singleRequestLayerIds)
                {
                    getLayerInfo(id, e.UserState);
                }
            }
            #endregion
        }
        public static void GetTitle(PopupItem popupItem, LayerInformation info)
        {
            if (popupItem == null)
            {
                return;
            }

            string titleExpression = string.Empty;
            string title           = string.Empty;

            Layer layer = popupItem.Layer;

            #region Get from developer override/webmap override
            //First get from developer override
            IDictionary <int, string> titleExpressions = ESRI.ArcGIS.Client.Extensibility.LayerProperties.GetPopupTitleExpressions(layer);
            //then if defined in web map
            if (titleExpressions == null && ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetUsePopupFromWebMap(layer))
            {
                titleExpressions = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetWebMapPopupTitleExpressions(layer);
            }
            if (titleExpressions != null)
            {
                if (layer is GraphicsLayer)
                {
                    titleExpression = (titleExpressions.ContainsKey(-1)) ? titleExpressions[-1] : null;
                }
                else
                {
                    titleExpression = (titleExpressions.ContainsKey(popupItem.LayerId)) ? titleExpressions[popupItem.LayerId] : null;
                }
            }
            #endregion

            #region Get title from expression
            if (!string.IsNullOrWhiteSpace(titleExpression))
            {
                title = ConvertExpressionWithFieldNames(popupItem, titleExpression);
            }
            #endregion

            if (string.IsNullOrWhiteSpace(title))
            {
                if (layer is GraphicsLayer) //get from display field set in layer configuration
                {
                    #region Get from display field - Graphics layer
                    string displayFieldName = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetDisplayField(layer as GraphicsLayer);
                    if (!string.IsNullOrWhiteSpace(displayFieldName))
                    {
                        object o = GetFieldValue(popupItem, displayFieldName);
                        title = (o != null) ? o.ToString() : string.Empty;
                        if (string.IsNullOrWhiteSpace(popupItem.TitleExpression))
                        {
                            titleExpression = "{" + displayFieldName + "}";
                        }
                    }
                    #endregion
                }
                else if (!ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetUsePopupFromWebMap(layer))
                {
                    #region Get from display field - dynamic layer
                    if (!string.IsNullOrEmpty(info.DisplayField))//get from display field set in layer configuration
                    {
                        object o = GetFieldValue(popupItem, info.DisplayField);
                        title           = (o != null) ? o.ToString() : string.Empty;
                        titleExpression = "{" + info.DisplayField + "}";
                    }
                    #endregion
                }
            }

            if (title != null)
            {
                title = title.Trim();
            }
            popupItem.Title           = title;
            popupItem.TitleExpression = titleExpression;
        }
 private void processLayerInfoResult(ArcGISWebClient.DownloadStringCompletedEventArgs e)
 {
     #region Parse layer info from json
     if (e.Cancelled)
         return;
     if (e.Error != null)
     {
         singleLayerRequestCompleted(null, e);
         return;
     }
     string json = null;
     try
     {
         json = e.Result;
     }
     catch (Exception exception)
     {
         if (exception != null)
         {
             singleLayerRequestCompleted(null, e);
             return;
         }
     }
     Exception ex = ESRI.ArcGIS.Mapping.DataSources.Utils.CheckJsonForException(json);
     if (ex != null)
     {
         singleLayerRequestCompleted(null, e);
         return;
     }
     json = "{\"layerDefinition\":" + json + "}";
     FeatureLayer featureLayer = FeatureLayer.FromJson(json);
     FeatureLayerInfo featurelayerinfo = featureLayer.LayerInfo;
     if (featurelayerinfo == null)
     {
         singleLayerRequestCompleted(null, e);
         return;
     }
     LayerInformation info = new LayerInformation()
     {
         ID = featurelayerinfo.Id,
         DisplayField = featurelayerinfo.DisplayField,
         Name = featurelayerinfo.Name,
         PopUpsEnabled = false,
         LayerJson = json,
         FeatureLayer = featureLayer
     };
     Collection<ESRI.ArcGIS.Mapping.Core.FieldInfo> fieldInfos = new Collection<ESRI.ArcGIS.Mapping.Core.FieldInfo>();
     if (featurelayerinfo.Fields != null)
     {
         foreach (ESRI.ArcGIS.Client.Field field in featurelayerinfo.Fields)
         {
             if (FieldHelper.IsFieldFilteredOut(field.Type))
                 continue;
             ESRI.ArcGIS.Mapping.Core.FieldInfo fieldInfo = ESRI.ArcGIS.Mapping.Core.FieldInfo.FieldInfoFromField(featureLayer, field);
             fieldInfos.Add(fieldInfo);
         }
     }
     info.Fields = fieldInfos;
     if (fieldInfos.Count > 0)
         singleLayerRequestCompleted(info, e);
     else
         singleLayerRequestCompleted(null, e);
     #endregion
 }
 void singleLayerRequestCompleted(LayerInformation info, object userState)
 {
     pendingRequests--;
     if (info != null)
         singleRequestLayerInfos.Add(info);
     if (pendingRequests < 1)
     {
         Collection<LayerInformation> layerinfos = new Collection<LayerInformation>();
         foreach (int id in singleRequestLayerIds)
         {
             foreach (LayerInformation item in singleRequestLayerInfos)
             {
                 if (item.ID == id)
                 {
                     layerinfos.Add(item);
                     break;
                 }
             }
         }
         onLayerInfosCompleted(new LayerInfosEventArgs() { LayerInfos = layerinfos, UserState = userState });
     }
 }
        private static void GetMappedAttributes(IDictionary<string, object> originalAttributes, LayerInformation info)
        {
            if (info == null || info.Fields == null)
                return;

            Dictionary<string, object> atts = new Dictionary<string, object>();
            foreach (KeyValuePair<string, object> origAtt in originalAttributes)
            {
                FieldInfo field = GetFieldByAliasOnServer(origAtt.Key, info.Fields);
                if (field != null)
                {
                    if (!atts.ContainsKey(field.Name))
                        atts.Add(field.Name, origAtt.Value);
                }
            }
            foreach (var item in atts)
                {
                if (!originalAttributes.ContainsKey(item.Key))
                    originalAttributes.Add(item);
                }

            return;
            }
        public static PopupItem GetPopupItem(Graphic graphic, Layer layer, IEnumerable<FieldInfo> fields, LayerInformation layerInfo, string layerName, string title = null, int? layerId = null)
        {
            if (layerInfo != null || layer is GraphicsLayer)
            {
                PopupItem popupItem = new PopupItem()
                {
                    Graphic = graphic,
                    Layer = layer,
                    Title = title,
                    LayerName = layerName,
                };
                if (layerId.HasValue) popupItem.LayerId = layerId.Value;

                if (layerInfo != null) GetMappedAttributes(graphic.Attributes, layerInfo);
                
                popupItem.FieldInfos = MapTipsHelper.ToFieldSettings(fields);
                MapTipsHelper.GetTitle(popupItem, layerInfo);

                bool hasContent = true;
                DataTemplate dt = MapTipsHelper.BuildMapTipDataTemplate(popupItem, out hasContent, layerInfo);
                if (!hasContent)
                    popupItem.DataTemplate = null;
                else if (dt != null)
                    popupItem.DataTemplate = dt;
                
                if (hasContent || (!string.IsNullOrWhiteSpace(popupItem.Title)))
                    return popupItem;

            }
            return null;
        }
        private void bindToGraphicsLayer(GraphicsLayer graphicsLayer)
        {
            object fields = graphicsLayer.GetValue(LayerExtensions.FieldsProperty);

            if (fields is IEnumerable<FieldInfo>)
            {
                string displayField = LayerExtensions.GetDisplayField(graphicsLayer);
                if (string.IsNullOrEmpty(displayField))
                {
                    displayField = FieldInfo.GetDefaultDisplayField(fields as IEnumerable<FieldInfo>);
                    if (!string.IsNullOrEmpty(displayField))
                        LayerExtensions.SetDisplayField(graphicsLayer, displayField);
                }

                #region Set data context
                MapTipsConfigInfo info = new MapTipsConfigInfo()
                {
                    LayerSelectionVisibility = false,
                    PopUpsOnClick = LayerExtensions.GetPopUpsOnClick(graphicsLayer),
					IsPopupEnabled = ESRI.ArcGIS.Client.Extensibility.LayerProperties.GetIsPopupEnabled(graphicsLayer),
                    Layer = graphicsLayer,
                };
                setFromWebMap(info);
                    info.SupportsOnClick = true;
                info.Layers = new Collection<LayerInformation>();

                LayerInformation item = new LayerInformation();
                item.PopUpsEnabled = true;
                item.ID = 0;
                item.Name = LayerExtensions.GetTitle(Layer);
                item.DisplayField = displayField;
                item.Fields = fields as Collection<FieldInfo>;
				if (graphicsLayer is FeatureLayer)
				{
					foreach (FieldInfo field in item.Fields)
					{
						if (field.DomainSubtypeLookup == DomainSubtypeLookup.NotDefined)
							field.DomainSubtypeLookup = FieldInfo.GetDomainSubTypeLookup(graphicsLayer, field);
					}
				}
                info.Layers.Add(item);
                info.SelectedItem = item;
                info.PropertyChanged += info_PropertyChanged;
                this.DataContext = info;
                #endregion
            }
        }