public static FieldInfo ChangeRenderer(this GraphicsLayer graphicsLayer, string rendererType, FieldInfo attributeField)
        {
            IRenderer newRenderer = null;
            GeometryType geometryType = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetGeometryType(graphicsLayer);
            LinearGradientBrush gradientBrush = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetGradientBrush(graphicsLayer);
            FieldInfo changedRenderAttributeField = null;
            List<Symbol> existingSymbolSet = null;
            if (Constants.ClassBreaksRenderer.Equals(rendererType))
            {
                int classBreakCount = 5;
                ClassBreaksRenderer currentRenderer = graphicsLayer.Renderer as ClassBreaksRenderer;
                if (currentRenderer != null)
                {
                    classBreakCount = currentRenderer.Classes.Count;
                    existingSymbolSet = new List<Symbol>();
                    foreach (ClassBreakInfo classBreak in currentRenderer.Classes)
                        existingSymbolSet.Add(classBreak.Symbol);
                }
                newRenderer = createClassBreakRendererBasedOnSelectedAttribute(graphicsLayer, attributeField, gradientBrush, geometryType, classBreakCount, existingSymbolSet, out changedRenderAttributeField);
            }
            else if (Constants.UniqueValueRenderer.Equals(rendererType))
            {
                UniqueValueRenderer currentRenderer = graphicsLayer.Renderer as UniqueValueRenderer;
                if (currentRenderer != null)
                {
                    existingSymbolSet = new List<Symbol>();
                    foreach (UniqueValueInfo uniqueValue in currentRenderer.Infos)
                        existingSymbolSet.Add(uniqueValue.Symbol);
                }
                newRenderer = createUniqueValueRendererBasedOnSelectedAttribute(graphicsLayer, attributeField, gradientBrush, geometryType, existingSymbolSet, out changedRenderAttributeField);
            }
            else if (Constants.SimpleRenderer.Equals(rendererType))
            {
                newRenderer = createNewDefaultSimpleRenderer(graphicsLayer);
            }

            assignNewRendererToLayer(graphicsLayer, newRenderer);
            if (changedRenderAttributeField != null)
                ESRI.ArcGIS.Mapping.Core.LayerExtensions.SetRendererAttributeDisplayName(graphicsLayer, changedRenderAttributeField.DisplayName);
            else if (attributeField != null)
                ESRI.ArcGIS.Mapping.Core.LayerExtensions.SetRendererAttributeDisplayName(graphicsLayer, attributeField.DisplayName);
            else
                ESRI.ArcGIS.Mapping.Core.LayerExtensions.SetRendererAttributeDisplayName(graphicsLayer, null);
            return changedRenderAttributeField;
        }
        internal void UpdateLayerRendererAttribute(FieldInfo attributeField)
        {
            if (AttributeName == null)
                return;

            _ignoreRendererTypeChangedEvent = true;
            _ignoreAttributeChangedEvent = true;
            buildDropDowns();
            _ignoreAttributeChangedEvent = false;
            _ignoreRendererTypeChangedEvent = false;
           
            //FieldInfo selectedField = null;            
            //foreach (FieldInfo fieldInfo in AttributeName.Items)
            //{
            //    if (string.Compare(fieldInfo.Name, attributeName) == 0)
            //    {
            //        selectedField = fieldInfo;
            //        break;
            //    }
            //}
            //if (selectedField != null)
            //{
            //    _ignoreAttributeChangedEvent = true;
            //    AttributeName.SelectedItem = selectedField;
            //    _ignoreAttributeChangedEvent = false;
            //}
        }
 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
 }
        private void sortFilterAndReBind(bool isSortAsc, FieldInfo sortField)
        {
            if (FeatureDataGrid == null)
                return;

            if (_graphicsLayer == null)
                return;

            NoAttributesLabelVisibility = Visibility.Collapsed;
            if (FilterFeaturesByMapExtent)
            {
                getFilterByMapExtentResultsWithRetry(isSortAsc, sortField);
            }
            else
            {
                _sortedGraphics = SortGraphics(_graphicsLayer.Graphics, isSortAsc, sortField);
                ApplyFilterBySelection();
                CheckForAttributes();
            }
        }
        /// <summary>
        /// Refreshes the Attribute Display list for graphics within the map extent
        /// </summary>
        private bool refreshByMapExtentNow(Rect mapExtentInHostCoordinates, bool isSortAsc, FieldInfo sortField, bool resetCount= true)
        {
            if (resetCount)
                _refreshLastResultCount = -1;

            try
            {
                if (mapExtentInHostCoordinates != Rect.Empty && _graphicsLayer != null)
                {
                    IEnumerable<Graphic> results = Core.Utility.FindGraphicsInHostCoordinates(_graphicsLayer, mapExtentInHostCoordinates);
                    if (results != null)
                    {
                        // load the Attribute Display with these results
                        int hitCount = results.Count();
                        // prevent the FDG from redundantly updating every time by checking the last results count
                        if (FeatureDataGrid.FilterSource == null || hitCount != _refreshLastResultCount)
                        {
                            _refreshLastResultCount = hitCount;
                            // update the feature data grid with the new results
                            applyResultsByExtentFromTimer(results, isSortAsc, sortField);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Instance.LogError(ex);
            }
            return false;
        }
        /// <summary>
        /// Finds graphics within the Envelope map area, with timer to
        /// retry every 500ms for 10 seconds
        /// </summary>
        /// <remarks>>If the timer is already running, this call will
        /// return without starting the timer.</remarks>
        /// <param name="envelope">null = entire map extent, otherwise as set</param>
        private void getFilterByMapExtentResultsWithRetry(bool isSortAsc, FieldInfo sortField, Envelope envelope= null)
        {
            if (FeatureDataGrid == null || _graphicsLayer == null || Map == null)
                return;

            if (envelope == null)
                envelope = Map.Extent;

            Dispatcher.BeginInvoke((Action)delegate
            {
                GeneralTransform transform = Transform.GetTransformToRoot(Map);
                Point ul = transform.Transform(Map.MapToScreen(new MapPoint(envelope.XMin, envelope.YMax)));
                Point lr = transform.Transform(Map.MapToScreen(new MapPoint(envelope.XMax, envelope.YMin)));
                Rect mapCoOrdinatesRect = new Rect(ul, lr);

                try
                {
                    refreshByMapExtentWithRetry(mapCoOrdinatesRect,isSortAsc,sortField);
                }
                catch (Exception ex)
                {
                    Logger.Instance.LogError(ex);
                }
            });
        }
        internal void RaiseSortedEvent(FieldInfo fieldInfo)
        {
            bool isSortAsc = _lastSortedField == fieldInfo ? !_isLastSortAsc : true;

            sortFilterAndReBind(isSortAsc, fieldInfo);

            _isLastSortAsc = isSortAsc;
            _lastSortedField = fieldInfo;

            OnSorted(new DataGridSortedEventArgs() { SortedField = fieldInfo });
        }
        private void ShowHideAutoGeneratedColumn(FieldInfo info)
        {
            if (info == null || FeatureDataGrid == null || FeatureDataGrid.Columns == null)
                return;

            foreach (DataGridColumn column in FeatureDataGrid.Columns)
            {
                FieldInfo headerInfo = column.Header as FieldInfo;
                if (headerInfo == info)
                {
                    column.Visibility = headerInfo.VisibleInAttributeDisplay ? Visibility.Visible : Visibility.Collapsed;//show/hide the column
                    return;
                }
            }
        }
        private static UniqueValueRenderer createUniqueValueRendererBasedOnSelectedAttribute(GraphicsLayer graphicsLayer, FieldInfo attributeField, LinearGradientBrush defaultColorRampGradientBrush, GeometryType geometryType, IEnumerable<Symbol> existingSymbolSet, out FieldInfo changedAttributeField)
        {
            changedAttributeField = attributeField;
            UniqueValueRenderer uniqueValueRenderer = graphicsLayer.Renderer as UniqueValueRenderer;
            if (uniqueValueRenderer != null) // already using unique value renderer
            {
                if (attributeField != null && attributeField.Name != uniqueValueRenderer.Field) // check if attribute has been changed
                {
                    IEnumerable<object> uniqueValues = getAllUniqueValues(graphicsLayer, attributeField);
                    uniqueValueRenderer = createNewDefaultUniqueValueRenderer(graphicsLayer, uniqueValues, attributeField, defaultColorRampGradientBrush, existingSymbolSet);
                }
            }
            else
            {
                string attributeFieldName = null;
                if (graphicsLayer.Renderer is ClassBreaksRenderer)
                {
                    // Check if the class breaks renderer had an attribute set. If so, honor that attribute name
                    ClassBreaksRenderer classBreakRenderer = graphicsLayer.Renderer as ClassBreaksRenderer;
                    if (classBreakRenderer != null)
                        attributeFieldName = classBreakRenderer.Field;
                }

                if (string.IsNullOrEmpty(attributeFieldName)) // No attribute known .. use the first non-attachment field
                {
                    FieldInfo field = null;
                    Collection<FieldInfo> layerFields = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetFields(graphicsLayer);
                    if (layerFields != null)
                        field = layerFields.FirstOrDefault<FieldInfo>(f => f.FieldType != FieldType.Attachment);
                    if (field != null)
                    {
                        changedAttributeField = field;
                        attributeField = field;
                        attributeFieldName = field.Name;
                    }
                }

                if (string.IsNullOrEmpty(attributeFieldName)) // An attribute name must be specified
                    return null;

                IEnumerable<object> uniqueValues = getAllUniqueValues(graphicsLayer, attributeField);
                // Create a default unique value renderer
                uniqueValueRenderer = createNewDefaultUniqueValueRenderer(graphicsLayer, uniqueValues, attributeField, defaultColorRampGradientBrush, existingSymbolSet);
            }
            return uniqueValueRenderer;
        }
        private static void getMinAndMaxForGraphicsLayer(GraphicsLayer graphicsLayer, FieldInfo attributeField, out double min, out double max)
        {
            min = double.NaN;
            max = double.NaN;
            if (graphicsLayer != null && attributeField != null && !string.IsNullOrEmpty(attributeField.Name))
            {
                foreach (Graphic g in graphicsLayer.Graphics)
                {
                    object o;
                    if (g.Attributes.TryGetValue(attributeField.Name, out o))
                    {
                        if (o == null)
                            continue;
                        double value;
                        NumericFieldValue numericFieldValue = o as NumericFieldValue;
                        if (numericFieldValue != null)
                        {
                            o = numericFieldValue.Value;
                        }
                        else
                        {
                            CurrencyFieldValue currencyFieldValue = o as CurrencyFieldValue;
                            if (currencyFieldValue != null)
                            {
                                o = currencyFieldValue.Value;
                            }
                        }

                        if (double.TryParse(
                            string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}", o),
                            System.Globalization.NumberStyles.Any,
                            System.Globalization.CultureInfo.InvariantCulture, out value))
                        {
                            if (double.IsNaN(min)) // first value
                                min = value;
                            else
                                min = Math.Min(min, value);

                            if (double.IsNaN(max)) // first value
                                max = value;
                            else
                                max = Math.Max(max, value);
                        }
                    }
                }
            }
            if (double.IsNaN(min))
                min = 0d;
            if (double.IsNaN(max))
                max = 0d;
        }
 private static IEnumerable<object> getAllUniqueValues(GraphicsLayer graphicsLayer, FieldInfo attributeField)
 {
     if (graphicsLayer == null || attributeField == null || string.IsNullOrEmpty(attributeField.Name))
         return null;
     List<object> uniqValues = new List<object>();
     foreach (Graphic g in graphicsLayer.Graphics)
     {
         object o;
         if (g.Attributes.TryGetValue(attributeField.Name, out o))
         {
             if (o == null)
                 continue; // ignore blank values
             string objString = o.ToString();
             if (string.IsNullOrEmpty(objString))
                 continue;
             if (!uniqValues.Contains(o))
                 uniqValues.Add(o);
         }
     }
     uniqValues.Sort();
     return uniqValues;
 }
 private static UniqueValueRenderer createNewDefaultUniqueValueRenderer(GraphicsLayer graphicsLayer, IEnumerable<object> uniqueValues, FieldInfo attributeField, LinearGradientBrush defaultColorRampGradientBrush, IEnumerable<Symbol> existingSymbolSet)
 {
     Symbol defaultSymbol = graphicsLayer.GetDefaultSymbol();
     UniqueValueRenderer uniqueValueRenderer = new UniqueValueRenderer()
     {
         Field = attributeField != null ? attributeField.Name : null,
         DefaultSymbol = defaultSymbol,
     };
     if (uniqueValues != null)
     {
         List<Symbol> symbols = new List<Symbol>();
         int i = 0;
         foreach (object uniqueValue in uniqueValues)
         {
             Symbol symbol = null;
             if (existingSymbolSet != null)
                 symbol = existingSymbolSet.ElementAtOrDefault(i);
             if (symbol == null)
                 symbol = graphicsLayer.GetDefaultSymbolClone();
             uniqueValueRenderer.Infos.Add(new UniqueValueInfoObj()
             {
                 Symbol = symbol,
                 SerializedValue = uniqueValue,
                 FieldType = attributeField.FieldType,
             });
             symbols.Add(symbol);
             i++;
         }
         if (defaultColorRampGradientBrush != null)
         {
             if (existingSymbolSet == null) // apply the gradient brush, only if symbols have not been pre-defined
             {
                 applyLinearGradientBrushToSymbolSet(symbols, defaultColorRampGradientBrush, defaultSymbol);
             }
         }
     }
     return uniqueValueRenderer;
 }
        private static IRenderer createNewDefaultClassBreaksRenderer(GraphicsLayer graphicsLayer, FieldInfo attributeField, double min, double max, int numOfClassBreaks, LinearGradientBrush defaultColorRampGradientBrush, IEnumerable<Symbol> existingSymbolSet)
        {
            Symbol defaultSymbol = graphicsLayer.GetDefaultSymbolClone();
            ClassBreaksRenderer renderer = new ClassBreaksRenderer()
            {
                Field = attributeField != null ? attributeField.Name : null,
                DefaultSymbol = defaultSymbol,
            };
            List<Symbol> symbols = new List<Symbol>();
            if (numOfClassBreaks < 2) // classbreaks renderer must have atleast 2 classbreaks
                numOfClassBreaks = 2;
            double rangeSize = Math.Round((max - min) / numOfClassBreaks, 2);
            double rangeDelta = 1.0; // delta between 2 class ranges // we choose an integral size
            double lastRangeDeltaIncr = 1.0; // SL core api requires the last classbreak to be greater than max value of dataset
            bool fractionalIncrement = false;
            if (Math.Round(max, 0) != max)// we are dealing with a non-integeral values, so our delta's are in fractional increments
            {
                fractionalIncrement = true;
                rangeDelta = 0.01;
                lastRangeDeltaIncr = 0.01;
            }

            double startValue = min;
            for (int i = 0; i < numOfClassBreaks; i++)
            {
                Symbol symbol = null;
                if (existingSymbolSet != null)
                    symbol = existingSymbolSet.ElementAtOrDefault(i);
                if (symbol == null)
                    symbol = graphicsLayer.GetDefaultSymbolClone();
                double endValue = (startValue + rangeSize) - rangeDelta;
                ClassBreakInfo classBreak = new ClassBreakInfo()
                {
                    MinimumValue = fractionalIncrement ? startValue : Math.Floor(startValue),
                    MaximumValue = fractionalIncrement ? endValue : Math.Floor(endValue),
                    Symbol = symbol,
                };
                if (i == numOfClassBreaks - 1) // last class break
                {
                    classBreak.MaximumValue = max + lastRangeDeltaIncr;
                    if (max > 1000000) // SL has a limitation on values greater than a million http://msdn.microsoft.com/en-us/library/bb412393.aspx
                        classBreak.MaximumValue += 2.0;// the +2 is to workaround Silverlights limitation of single precision values
                }
                symbols.Add(symbol);
                renderer.Classes.Add(classBreak);
                startValue += rangeSize;
            }
            if (defaultColorRampGradientBrush != null)
            {
                if (existingSymbolSet == null) // apply the gradient brush, only if symbols have not been pre-defined
                {
                    applyLinearGradientBrushToSymbolSet(symbols, defaultColorRampGradientBrush, defaultSymbol);
                }
            }
            return renderer;
        }
        private static IRenderer createClassBreakRendererBasedOnSelectedAttribute(GraphicsLayer graphicsLayer, FieldInfo attributeField, LinearGradientBrush defaultColorRampGradientBrush, GeometryType geometryType, int classBreakCount, IEnumerable<Symbol> existingSymbolSet, out FieldInfo changedAttributeField)
        {
            changedAttributeField = attributeField;
            ClassBreaksRenderer classBreaksRenderer = graphicsLayer.Renderer as ClassBreaksRenderer;
            if (classBreaksRenderer != null) // Already using classBreaksRenderer
            {
                if (attributeField != null && attributeField.Name != classBreaksRenderer.Field) // Using different attribute for the renderer
                {
                    classBreaksRenderer.Field = attributeField.Name;

                    // Rebuild the class breaks
                    double min, max;
                    getMinAndMaxForGraphicsLayer(graphicsLayer, attributeField, out min, out max);

                    return createNewDefaultClassBreaksRenderer(graphicsLayer, attributeField, min, max, classBreakCount, defaultColorRampGradientBrush, existingSymbolSet);
                }
            }
            else
            {
                string attributeFieldName = null;
                if (graphicsLayer.Renderer is UniqueValueRenderer)
                {
                    // 1. Check if the renderer has an attribute set as UniqueValue Renderer
                    UniqueValueRenderer uniqueValueRenderer = graphicsLayer.Renderer as UniqueValueRenderer;
                    if (uniqueValueRenderer != null)
                        attributeFieldName = uniqueValueRenderer.Field;
                }

                if (string.IsNullOrEmpty(attributeFieldName)) // No attribute known .. use the first numeric field
                {
                    FieldInfo field = null;
                    Collection<FieldInfo> layerFields = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetFields(graphicsLayer);
                    if (layerFields != null)
                        field = layerFields.FirstOrDefault<FieldInfo>(f => f.FieldType == FieldType.DecimalNumber || f.FieldType == FieldType.Integer || f.FieldType == FieldType.Currency);
                    if (field != null)
                    {
                        attributeField = field;
                        changedAttributeField = field;
                        attributeFieldName = field.Name;
                    }
                }
                else
                {
                    FieldInfo field = null;
                    Collection<FieldInfo> layerFields = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetFields(graphicsLayer);
                    if (layerFields != null)
                        field = layerFields.FirstOrDefault<FieldInfo>(f => f.Name == attributeFieldName); // find matching field
                    if (field == null || (field.FieldType != FieldType.Integer && field.FieldType != FieldType.DecimalNumber && field.FieldType != FieldType.Currency))
                    {
                        // if the previous field was not a number or currency, then automatically switch it to the first numeric one
                        field = layerFields.FirstOrDefault<FieldInfo>(f => f.FieldType == FieldType.Integer || f.FieldType == FieldType.DecimalNumber || f.FieldType == FieldType.Currency);
                        if (field != null)
                        {
                            attributeField = field;
                            changedAttributeField = field;
                            attributeFieldName = field.Name;
                        }
                    }
                }

                if (string.IsNullOrEmpty(attributeFieldName)) // An attribute name must be specified
                    return null;

                // Loop through graphics and calculate max and min
                double min, max;
                getMinAndMaxForGraphicsLayer(graphicsLayer, attributeField, out min, out max);

                return createNewDefaultClassBreaksRenderer(graphicsLayer, attributeField, min, max, classBreakCount, defaultColorRampGradientBrush, existingSymbolSet);
            }
            return null;
        }
        public static FieldInfo ChangeAttributeForRenderer(this GraphicsLayer graphicsLayer, FieldInfo newAttributeField)
        {
            IRenderer newRenderer = null;
            GeometryType geometryType = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetGeometryType(graphicsLayer);
            LinearGradientBrush gradientBrush = ESRI.ArcGIS.Mapping.Core.LayerExtensions.GetGradientBrush(graphicsLayer);
            FieldInfo changedAttribute = null;
            List<Symbol> existingSymbolSet;
            ClassBreaksRenderer classBreaksRenderer = graphicsLayer.Renderer as ClassBreaksRenderer;
            if (classBreaksRenderer != null)
            {
                existingSymbolSet = new List<Symbol>();
                foreach (ClassBreakInfo classBreak in classBreaksRenderer.Classes)
                    existingSymbolSet.Add(classBreak.Symbol);
                newRenderer = createClassBreakRendererBasedOnSelectedAttribute(graphicsLayer, newAttributeField, gradientBrush, geometryType, classBreaksRenderer.Classes.Count, existingSymbolSet, out changedAttribute);
            }
            else
            {
                UniqueValueRenderer uniqueValueRenderer = graphicsLayer.Renderer as UniqueValueRenderer;
                if (uniqueValueRenderer != null)
                {
                    existingSymbolSet = new List<Symbol>();
                    foreach (UniqueValueInfo uniqueValue in uniqueValueRenderer.Infos)
                        existingSymbolSet.Add(uniqueValue.Symbol);
                    newRenderer = createUniqueValueRendererBasedOnSelectedAttribute(graphicsLayer, newAttributeField, gradientBrush, geometryType, existingSymbolSet, out changedAttribute);
                }
            }

            assignNewRendererToLayer(graphicsLayer, newRenderer);
            graphicsLayer.Refresh();
            if (changedAttribute != null)
                ESRI.ArcGIS.Mapping.Core.LayerExtensions.SetRendererAttributeDisplayName(graphicsLayer, changedAttribute.DisplayName);
            else if (newAttributeField != null)
                ESRI.ArcGIS.Mapping.Core.LayerExtensions.SetRendererAttributeDisplayName(graphicsLayer, newAttributeField.DisplayName);
            else
                ESRI.ArcGIS.Mapping.Core.LayerExtensions.SetRendererAttributeDisplayName(graphicsLayer, null);
            return changedAttribute;
        }
        private void determineFieldsFromGraphic(Collection<FieldInfo> layerFields, Graphic graphic)
        {
            if (graphic == null || layerFields == null)
                return;

            foreach (KeyValuePair<string, object> pair in graphic.Attributes)
            {
                FieldInfo field = new FieldInfo() { Name = pair.Key, DisplayName = pair.Key, VisibleInAttributeDisplay = true, VisibleOnMapTip = true };                
                if (pair.Value is DateTime)
                    field.FieldType = FieldType.DateTime;
                else if (pair.Value is double || pair.Value is decimal)
                    field.FieldType = FieldType.DecimalNumber;
                else if (pair.Value is int || pair.Value is byte)
                    field.FieldType = FieldType.Integer;
                else
                    field.FieldType = FieldType.Text;
                layerFields.Add(field);
            }
        }
        private CustomDataGridColumn createDataGridColumnForField(FieldInfo field)
        {
            string fieldName = field.Name;
            if (doesfieldNeedNormalization(fieldName))
            {
                fieldName = normalizeFieldName(fieldName);
            }

            CustomDataGridColumn col = new CustomDataGridColumn()
            {
                Header = field,
                IsReadOnly = true,
                Binding = new Binding()
                {
                    // Use a converter to retrieve the field value.  Otherwise, the binding
                    // will blow up on field names that are numeric - and perhaps others
                    Converter = new RowToFieldValueConverter(),
                    ConverterParameter = fieldName
                },
                FieldInfo = field,
            };
            return col;
        }
        private void bindUI()
        {
            if (LayerInfo == null)
                return;
            object fields = LayerInfo.Fields;
             if (fields != null)
             {
                 if (MapTipsDataGrid != null)
                 {
                     MapTipsDataGrid.IsEnabled = true;
                     MapTipsDataGrid.ItemsSource = fields as IEnumerable<FieldInfo>;
                 }
                 if (ToggleAllVisibilityButton != null)
                     ToggleAllVisibilityButton.IsEnabled = true;
                 if (fields is Collection<FieldInfo>)
                 {
                     CheckToggleButtonState(fields as IEnumerable<FieldInfo>);
                 }
                 if (HeaderCombo != null && fields is IEnumerable<FieldInfo>)
                 {
                     string displayField = LayerInfo.DisplayField;
                     Collection<FieldInfo> filteredFields = new Collection<FieldInfo>();
                     // if not set for popup on click, add <none>
                     FieldInfo selectedItem = null;
                     if (Info != null && Info.PopUpsOnClick != null && !Info.PopUpsOnClick.Value && !Info.LayerSelectionVisibility)
                     {
                        FieldInfo noneField = new FieldInfo() { Name = ESRI.ArcGIS.Mapping.Core.LocalizableStrings.NoneInAngleBraces };
                        filteredFields.Add(noneField);
                        selectedItem = noneField;

                     }

                     foreach (FieldInfo item in fields as IEnumerable<FieldInfo>)
                     {
                         if (FieldInfo.SupportedInHeader(item.FieldType))
                         {
                             filteredFields.Add(item);

                             if (!string.IsNullOrEmpty(displayField))
                             {
                                 if (item.Name.ToLower().Equals(displayField.ToLower()))
                                     selectedItem = item;
                             }
                         }
                     }
                     HeaderCombo.ItemsSource = filteredFields;
                     HeaderCombo.IsEnabled = true;
                     HeaderCombo.SelectedItem = selectedItem;
                 }
             }
             else
             {
                 if (MapTipsDataGrid != null)
                 {
                     MapTipsDataGrid.IsEnabled = false;
                     MapTipsDataGrid.ItemsSource = null;
                 }
                 if (ToggleAllVisibilityButton != null)
                     ToggleAllVisibilityButton.IsEnabled = false;
                 if (HeaderCombo != null)
                 {
                     HeaderCombo.ItemsSource = null;
                     HeaderCombo.IsEnabled = false;
                 }
             }
        }
 private int findInsertIndexOfField(FieldInfo field)
 {
     int pos = 0;
     Collection<FieldInfo> fields = LayerExtensions.GetFields(GraphicsLayer);
     if (fields != null)
     {
         foreach (FieldInfo f in fields)
         {
             if (f.Name == field.Name)
                 break;
             if (!f.VisibleInAttributeDisplay) // skip non visible fields
                 continue;
             pos++;
         }
     }
     return pos;
 }
        internal void FieldInfo_MapTipVisiblityChecked(FieldInfo fieldInfo)
        {
            if (fieldInfo == null)
                return;

            GraphicsLayer graphicsLayer = Layer as GraphicsLayer;
            if (graphicsLayer != null)
                LayerExtensions.SetIsMapTipDirty(graphicsLayer, true);

           
            bool visible = !isClearAllState;
            IEnumerable<FieldInfo> fields = LayerInfo.Fields;
            if (fields == null)
                return;

            // For feature layers - add the name of the field to the OutFields collection
            FeatureLayer featureLayer = Layer as FeatureLayer;
            if (featureLayer != null)
            {

                if (featureLayer.OutFields.Count == 1 && featureLayer.OutFields[0] == "*")
                {
                    reBuildOutFields(featureLayer, fields);
                }
                else
                {
                    if (!featureLayer.OutFields.Contains(fieldInfo.Name))
                        featureLayer.OutFields.Add(fieldInfo.Name);
                }
            }

            CheckToggleButtonState(fields);
        }               
        internal void OnGraphicsLayerChanged(GraphicsLayer newGraphicsLayer)
        {
            detachHandlers();

            _graphicsLayer = newGraphicsLayer;
            _isLastSortAsc = false;
            _lastSortedField = null;
            _sortedGraphics = null;
            attachHandlers();

            bindGraphicsLayerToDataGrid();
        }
        internal void FieldInfo_MapTipVisibilityUnChecked(FieldInfo fieldInfo)
        {
            if (fieldInfo == null)
                return;
            
            GraphicsLayer graphicsLayer = Layer as GraphicsLayer;
            if (graphicsLayer != null)
                LayerExtensions.SetIsMapTipDirty(graphicsLayer, true);

            bool visible = !isClearAllState;
            IEnumerable<FieldInfo> fields = LayerInfo.Fields;
            if (fields == null)
                return;

            // For feature layers - remove the name of the field to the OutFields collection
            FeatureLayer featureLayer = Layer as FeatureLayer;
            if (featureLayer != null)
            {
                if (featureLayer.OutFields.Count == 1 && featureLayer.OutFields[0] == "*")
                {
                    reBuildOutFields(featureLayer, fields);
                }
                else
                {
                    // in not also visible in attribute display and not the renderer field = remove it
                    if (!fieldInfo.VisibleInAttributeDisplay && !isRendererField(fieldInfo))
                    {
                        featureLayer.OutFields.Remove(fieldInfo.Name);
                    }
                }
            }

            CheckToggleButtonState(fields);
        }
        /// <summary>
        /// Refreshes the Attribute Display and uses a retry mechanism if the initial attempts to refresh
        /// do not return any graphics (in case the layer is large and has not fully loaded yet)
        /// </summary>
        private void refreshByMapExtentWithRetry(Rect mapExtentInHostCoordinates, bool isSortAsc, FieldInfo sortField)
        {
            try
            {
                if (_refreshTimer != null)
                {
                    _refreshTimer.Stop();
                }
                else
                {
                    _refreshTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, 500) };
                    _refreshTimerTicks = 0;

                    #region Timer Tick handler

                    _refreshTimer.Tick += (s, e) =>
                            {
                                if (_isRefreshing)
                                    return;

                                try
                                {
                                    _refreshTimerTicks++;
                                    // Try another refresh checking 20 times (10 seconds after the layer was added)
                                    if (_refreshTimerTicks < 20)
                                    {
                                        _isRefreshing = true;
                                        try
                                        {
                                            refreshByMapExtentNow(mapExtentInHostCoordinates,
                                                                isSortAsc, sortField, resetCount:false);
                                        }
                                        finally
                                        {
                                            _isRefreshing = false;
                                        }
                                    }
                                    else
                                    {
                                        _refreshTimer.Stop();
                                        _refreshTimer = null;
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine(ex);
                                    if (_refreshTimer != null)
                                    {
                                        _refreshTimer.Stop();
                                        _refreshTimer = null;
                                    }
                                }
                            };

                    #endregion
                }

                // Attempt refresh using filter by map extent
                refreshByMapExtentNow   (mapExtentInHostCoordinates, isSortAsc, sortField);

                // The refresh did not find any graphics.  This may be due to a 
                // layer with a lot of features that has not fully loaded yet.

                _refreshTimer.Start();
            }
            catch (Exception ex2)
            {
                Console.WriteLine(ex2);
                if (_refreshTimer != null)
                {
                    _refreshTimer.Stop();
                    _refreshTimer = null;
                }
            }
        }
        private bool isRendererField(FieldInfo field)
        {
            if (field == null)
                return false;

            string rendererAttr = getRendererAttributeName();
            if (rendererAttr == field.Name)
                return true;

            return false;
        }
        private void applyResultsByExtentFromTimer(IEnumerable<Graphic> results, bool isSortAsc, FieldInfo sortField)
        {
            if (results == null) return;

            // load the attribute display with the graphics within the map extent
            _sortedGraphics = SortGraphics(results, isSortAsc, sortField);
            ApplyFilterBySelection();
            CheckForAttributes();
        }
            // TODO: Support StringFieldOptions

            internal static FieldInfo FromDictionary(IDictionary<string, object> dictionary)
            {
                FieldInfo fi = new FieldInfo();

                if (dictionary.ContainsKey("fieldName"))
                    fi.FieldName = dictionary["fieldName"] as string;
                if (dictionary.ContainsKey("label"))
                    fi.Label = dictionary["label"] as string;
                if (dictionary.ContainsKey("formatter"))
                    fi.Formatter = dictionary["formatter"] as string;
                if (dictionary.ContainsKey("visible"))
                    fi.Visible = Convert.ToBoolean(dictionary["visible"]);
                if (dictionary.ContainsKey("isEditable"))
                    fi.IsEditable = Convert.ToBoolean(dictionary["isEditable"]);
                if (dictionary.ContainsKey("tooltip"))
                    fi.Tooltip = dictionary["tooltip"] as string;
                // TODO: Add support for stringFieldOptions

                return fi;
            }
 internal IEnumerable<Graphic> SortGraphics(IEnumerable<Graphic> graphics, bool isSortAsc, FieldInfo sortField)
 {
     if (sortField != null)
     {
         bool sortable = false;
         Type dataType = null;
         foreach (Graphic graphic in graphics)
         {
             if (graphic.Attributes[sortField.Name] != null)
             {
                 sortable = graphic.Attributes[sortField.Name] is IComparable;
                 dataType = graphic.Attributes[sortField.Name].GetType();
                 break;
             }
         }
         if (sortable && dataType != null)
         {
             if (isSortAsc)
                 graphics = graphics.OrderBy(r => (
                      (r.Attributes[sortField.Name] != null && r.Attributes[sortField.Name].GetType() == dataType) ?
                      r.Attributes[sortField.Name] : null));
             else
                 graphics = graphics.OrderByDescending(r => (
                      (r.Attributes[sortField.Name] != null && r.Attributes[sortField.Name].GetType() == dataType) ?
                      r.Attributes[sortField.Name] : null));
         }
     }
     return graphics;
 }
        public static object GetDomainValue(FeatureLayer featureLayer, IDictionary<string, object> attibutes, FieldInfo field)
		{
			object originalValue = string.Empty;
			string fieldName = string.Empty;
            if (featureLayer == null)
                return originalValue;
			if (field != null)
				fieldName = field.Name;
			if (attibutes != null)
			{
				originalValue = attibutes[field.Name];
				if (originalValue == null)
				{
					if (attibutes.ContainsKey(field.DisplayName))
					{
						fieldName = field.DisplayName;
						originalValue = attibutes[field.DisplayName];
					}
					else
						return originalValue;
				}
			}
			if (featureLayer == null)
				return originalValue;
			if (field.DomainSubtypeLookup == DomainSubtypeLookup.None || field.DomainSubtypeLookup == DomainSubtypeLookup.NotDefined)
				return originalValue;
			ESRI.ArcGIS.Client.FeatureService.FeatureLayerInfo featureLayerInfo = featureLayer.LayerInfo;
			if (featureLayerInfo == null)
				return originalValue;
			IDictionary<object, FeatureType> featureTypes = featureLayerInfo.FeatureTypes;
			if ((featureTypes == null) && (field.DomainSubtypeLookup != DomainSubtypeLookup.FieldDomain)) return originalValue;
			if (attibutes == null) return originalValue;
			string domainCodedValue = string.Empty;
			object typeIdValue = null;
			switch (field.DomainSubtypeLookup)
			{
				case DomainSubtypeLookup.NotDefined:
				case DomainSubtypeLookup.None:
					break;
				case DomainSubtypeLookup.FieldDomain:
					Client.Field f = GetField(field.Name, featureLayerInfo.Fields);
					if (f == null) return originalValue;
					return GetDomainValue(originalValue, f.Domain as CodedValueDomain);
				case DomainSubtypeLookup.TypeIdField:
					if (!attibutes.ContainsKey(featureLayerInfo.TypeIdField))
						return originalValue;
					typeIdValue = attibutes[featureLayerInfo.TypeIdField];
					foreach (KeyValuePair<object, FeatureType> item in featureLayerInfo.FeatureTypes)
					{
						if (item.Key.Equals(typeIdValue) && item.Value != null)
							return item.Value.Name;
					}
					break;
				case DomainSubtypeLookup.FeatureTypeDomain:
					if (!attibutes.ContainsKey(featureLayerInfo.TypeIdField))
						return originalValue;
					typeIdValue = attibutes[featureLayerInfo.TypeIdField];
					foreach (KeyValuePair<object, FeatureType> fTypePair in featureLayerInfo.FeatureTypes)
					{
						if (fTypePair.Key.Equals(typeIdValue) && fTypePair.Value != null && fTypePair.Value.Domains != null)
						{
							foreach (KeyValuePair<string, Domain> pair in fTypePair.Value.Domains)
							{
								if (pair.Key.Equals(field.Name) && pair.Value is CodedValueDomain)
								{
									return GetDomainValue(originalValue, pair.Value as CodedValueDomain);
								}
							}
						}
					}
					break;
				default:
					break;
			}
			return originalValue;
		}
Example #29
0
        private void PerformPostLayerInitializationActions(Layer layer, bool initializationSuccess)
        {
            GraphicsLayer gLayer = layer as GraphicsLayer;

            if (gLayer != null)
            {
                GeometryType           geometryType = Core.LayerExtensions.GetGeometryType(gLayer);
                Collection <FieldInfo> layerFields  = Core.LayerExtensions.GetFields(gLayer);
                FeatureLayer           featureLayer = layer as FeatureLayer;
                if (layerFields.Count == 0 &&
                    featureLayer != null && featureLayer.LayerInfo != null && featureLayer.LayerInfo.Fields != null)
                {
                    foreach (ESRI.ArcGIS.Client.Field field in featureLayer.LayerInfo.Fields)
                    {
                        if (FieldHelper.IsFieldFilteredOut(field.Type))
                        {
                            continue;
                        }
                        ESRI.ArcGIS.Mapping.Core.FieldInfo fieldInfo = ESRI.ArcGIS.Mapping.Core.FieldInfo.FieldInfoFromField(featureLayer, field);
                        layerFields.Add(fieldInfo);
                    }
                }
                if (gLayer.Graphics != null)
                {
                    #region Get geometry type, start getting symbology
                    if (geometryType == GeometryType.Unknown && gLayer.Graphics.Count > 0)
                    {
                        geometryType = LayerUtils.GetGeometryTypeFromGraphic(gLayer.Graphics.ElementAtOrDefault(0));
                        Core.LayerExtensions.SetGeometryType(gLayer, geometryType);

                        if ((gLayer.Renderer == null || gLayer.Renderer is HiddenRenderer) && !Symbology.DefaultSymbols.ContainsKey(geometryType))
                        {
                            if (geometryType == GeometryType.Unknown)
                            {
                                gLayer.SetValue(ESRI.ArcGIS.Client.Extensibility.LayerExtensions.ErrorMessageProperty, "Layer has unspecified geometry type.");
                            }
                            else
                            {
                                Core.LayerExtensions.SetRunLayerPostInitializationActions(gLayer, true);
                                SymbolConfigProvider.GetDefaultLinearGradientBrush(gLayer, ColorRampType.ClassBreaks);
                            }
                            return;
                        }
                    }
                    #endregion

                    #region Project graphics if necessary
                    if (graphicsRequireReprojection(gLayer.Graphics))
                    {
                        GeometryServiceOperationHelper helper = new GeometryServiceOperationHelper(
                            new ConfigurationStoreHelper().GetGeometryServiceUrl(ConfigurationStore)
                            );
                        helper.ProjectGraphicsCompleted += (sender, args) =>
                        {
                            GraphicsLayer targetLayer = args.UserState as GraphicsLayer;
                            if (targetLayer != null)
                            {
                                targetLayer.Graphics.Clear();
                                foreach (Graphic graphic in args.Graphics)
                                {
                                    targetLayer.Graphics.Add(graphic);
                                }
                            }
                        };
                        helper.ProjectGraphics(gLayer.Graphics, Map.SpatialReference, gLayer);
                    }
                    #endregion

                    #region Get field information
                    if (layerFields.Count == 0) // fields not determined yet
                    {
                        determineFieldsFromGraphic(layerFields, gLayer.Graphics.ElementAtOrDefault(0));
                    }
                    #endregion
                }

                #region Get renderer from feature layer's layer info, if necessary
                if (gLayer.Renderer == null || gLayer.Renderer is HiddenRenderer)
                {
                    FeatureLayer lay = gLayer as FeatureLayer;
                    if (lay != null && lay.LayerInfo != null && lay.LayerInfo.Renderer != null)
                    {
                        lay.Renderer = lay.LayerInfo.Renderer;
                    }
                }
                #endregion

                #region Change PictureMarkerSymbol to ImageFillSymbol
                if (gLayer.Renderer != null && (geometryType == GeometryType.Point || geometryType == GeometryType.MultiPoint))
                {
                    SimpleRenderer sr = gLayer.Renderer as SimpleRenderer;
                    ESRI.ArcGIS.Client.FeatureService.Symbols.PictureMarkerSymbol pms = null;
                    if (sr != null)
                    {
                        pms = sr.Symbol as ESRI.ArcGIS.Client.FeatureService.Symbols.PictureMarkerSymbol;
                        if (pms != null)
                        {
                            sr.Symbol = SymbolJsonHelper.ToImageFillSymbol(pms);
                        }
                    }
                    else
                    {
                        ClassBreaksRenderer cbr = gLayer.Renderer as ClassBreaksRenderer;
                        if (cbr != null)
                        {
                            foreach (ClassBreakInfo info in cbr.Classes)
                            {
                                pms = info.Symbol as ESRI.ArcGIS.Client.FeatureService.Symbols.PictureMarkerSymbol;
                                if (pms != null)
                                {
                                    info.Symbol = SymbolJsonHelper.ToImageFillSymbol(pms);
                                }
                            }
                        }
                        else
                        {
                            UniqueValueRenderer uvr = gLayer.Renderer as UniqueValueRenderer;
                            if (uvr != null)
                            {
                                foreach (UniqueValueInfo info in uvr.Infos)
                                {
                                    pms = info.Symbol as ESRI.ArcGIS.Client.FeatureService.Symbols.PictureMarkerSymbol;
                                    if (pms != null)
                                    {
                                        info.Symbol = SymbolJsonHelper.ToImageFillSymbol(pms);
                                    }
                                }
                            }
                        }
                    }
                }
                #endregion

                if (gLayer.Renderer == null || gLayer.Renderer is HiddenRenderer)
                {
                    ApplyDefaultRenderer(gLayer, geometryType);
                }

                ApplyDefaultGradientBrush(gLayer);
            }
            else if ((layer is ArcGISDynamicMapServiceLayer || layer is ArcGISTiledMapServiceLayer) &&
                     !((bool)layer.GetValue(ESRI.ArcGIS.Client.WebMap.Document.IsBaseMapProperty)))
            {
                //get layer infos - used later for figuring out domain/subtypes, etc
                if ((layer.GetValue(ESRI.ArcGIS.Mapping.Core.LayerExtensions.LayerInfosProperty) as Collection <LayerInformation>)
                    == null)
                {
                    getLayerInfos(layer);
                }
            }
            bool doSelect = false;
            layer.SetValue(ESRI.ArcGIS.Client.Extensibility.LayerExtensions.InitialUpdateCompletedProperty, true);
            if (!initializationSuccess)
            {
                layer.SetValue(ESRI.ArcGIS.Client.Extensibility.LayerExtensions.InitialUpdateFailedProperty, true);
            }
            else
            {
                bool hasId = !string.IsNullOrEmpty(layer.ID) || !string.IsNullOrEmpty(layer.GetValue(ESRI.ArcGIS.Client.Extensibility.MapApplication.LayerNameProperty) as  string);
                // Certain layers get added when the map draw mode is changed (An empty graphics layer is added)
                // We don't want to auto-select this layer
                if (hasId || !(layer is GraphicsLayer))
                {
                    doSelect = true;
                }
            }

            if (doSelect)
            {
                SetSelectedLayer(new LayerEventArgs()
                {
                    Layer = layer
                });
            }

            SubscribeToLayerInitializationEvents(layer, false);
        }
        private void parseLayerDetailsFromResponse(string jsonResponse)
        {
            using (MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(jsonResponse)))
            {
                DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(LayerDetails));
                LayerDetails layerDetails = dataContractJsonSerializer.ReadObject(memoryStream) as LayerDetails;
                if (layerDetails != null)
                {
                    foreach (Field field in layerDetails.Fields)
                    {
                        FieldInfo fieldInfo = new FieldInfo()
                       {
                           DisplayName = field.Alias,
                           Name = field.Name,
                           FieldType = field.Type,
                           VisibleOnMapTip = true
                       };
                        _fields.Add(fieldInfo);
                        if (field.Type == "esriFieldTypeInteger"
                            || field.Type == "esriFieldTypeSmallInteger"
                            || field.Type == "esriFieldTypeDouble")
                        {
                            NumericFields.Add(fieldInfo);
                        }
                    }
                    switch (layerDetails.GeometryType)
                    {
                        case "esriGeometryPoint":
                            GeometryType = GeometryType.Point;
                            break;
                        case "esriGeometryPolyline":
                            GeometryType = GeometryType.Polyline;
                            break;
                        case "esriGeometryPolygon":
                            GeometryType = GeometryType.Polygon;
                            break;
                    }
                }
            }

            // Now that all Metadata has been retrieved .. call base.initialize
            base.Initialize();           
        }
		public static DomainSubtypeLookup GetDomainSubTypeLookup(Layer layer, FieldInfo field)
		{
			if (field.DomainSubtypeLookup != DomainSubtypeLookup.NotDefined)
				return field.DomainSubtypeLookup;
			ESRI.ArcGIS.Client.FeatureLayer featureLayer = layer as ESRI.ArcGIS.Client.FeatureLayer;
			if (featureLayer == null)
			{
				field.DomainSubtypeLookup = DomainSubtypeLookup.None;
				return field.DomainSubtypeLookup;
			}
			ESRI.ArcGIS.Client.FeatureService.FeatureLayerInfo featureLayerInfo = featureLayer.LayerInfo;
			if (featureLayerInfo != null)
			{
				Client.Field f = GetField(field.Name, featureLayerInfo.Fields);
				field.DomainSubtypeLookup = GetDomainSubTypeLookup(featureLayerInfo, f);
			}
			return field.DomainSubtypeLookup;
		}
        internal void FieldInfo_AttributeDisplayUnChecked(FieldInfo fieldInfo)
        {
            if (fieldInfo == null)
                return;

            // For feature layers - remove the name of the field to the OutFields collection
            FeatureLayer featureLayer = Layer as FeatureLayer;
            if (featureLayer == null)
                return;

            bool visible = !isClearAllState;
            IEnumerable<FieldInfo> fields = featureLayer.GetValue(LayerExtensions.FieldsProperty) as IEnumerable<FieldInfo>;
            if (fields == null)
                return;
            
            if (featureLayer.OutFields.Count == 1 && featureLayer.OutFields[0] == "*")
            {
                reBuildOutFields(featureLayer, fields);                
            }
            else
            {
                // in not also visible in map tip display and not used as  = remove it
                if (!fieldInfo.VisibleOnMapTip && !isRendererField(fieldInfo)) 
                {
                    featureLayer.OutFields.Remove(fieldInfo.Name);
                }
            }

            CheckToggleButtonState(fields);
        }