/// <summary>
        /// Runs a test query against the specified date field to determine the type of data source.
        /// </summary>
        private static void QueryDate(string dataSetUrl, bool useProxy, SubLayerField dateField, string dataSource, EventHandler <DataSourceEventArgs> callback)
        {
            DateTime testDate = new DateTime(1977, 12, 01, 0, 0, 0, 0);

            QueryTask qT = new QueryTask(dataSetUrl);

            if (useProxy)
            {
                qT.ProxyURL = ArcGISOnlineEnvironment.ConfigurationUrls.ProxyServerEncoded;
            }

            ESRI.ArcGIS.Client.Tasks.Query q = new ESRI.ArcGIS.Client.Tasks.Query();
            q.OutFields.Add(dateField.Name);
            q.Where          = dateField.Name + " = " + Format(testDate, dataSource);
            q.ReturnGeometry = false;

            EventHandler <ESRI.ArcGIS.Client.Tasks.QueryEventArgs> completedHandler = null;

            completedHandler = (object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs e) =>
            {
                callback(null, new DataSourceEventArgs()
                {
                    DataSource = dataSource
                });
            };

            qT.ExecuteCompleted += completedHandler;

            //execute the query
            //
            qT.ExecuteAsync(q);
        }
 /// <summary>
 /// Determines the data source type asynchronously from a date field by running a series of test queries against it.
 /// </summary>
 /// <remarks>
 /// If a test query succeeds the data source type is reported back to the client via the callback. It is possible that
 /// multiple queries succeed so the client is called back multiple times.
 /// </remarks>
 /// <param name="dataSetUrl">The data set that contains the dateField.</param>
 /// <param name="dateField">A date field used to determine the data source type.</param>
 /// <param name="callback">A event handler that is called back when a test query succeeds. Multiple callbacks are possible.</param>
 public static void GetDataSource(string dataSetUrl, bool useProxy, SubLayerField dateField, EventHandler <DataSourceEventArgs> callback)
 {
     foreach (string dataSource in SupportedDataSources)
     {
         QueryDate(dataSetUrl, useProxy, dateField, dataSource, callback);
     }
 }
        /// <summary>
        /// Occurs when a field is selected. Adds the field to the where clause then
        /// clears the FieldListBox selection.
        /// </summary>
        internal void FieldListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            SubLayerField field = FieldListBox.SelectedItem as SubLayerField;

            if (field != null)
            {
                AddText(field.Name);
            }

            FieldListBox.SelectedItem = null;
        }
        /// <summary>
        /// If the feature layer contains fields of type Date, runs a sequence of test queries to determine
        /// the date format required by the underlying data source.
        /// </summary>
        private void SetupDateFormat()
        {
            if (QueryProperties.SubLayerDescription.Fields == null)
            {
                return;
            }

            SubLayerField dateField = null;

            foreach (SubLayerField field in QueryProperties.SubLayerDescription.Fields)
            {
                if (field.Type == "esriFieldTypeDate")
                {
                    dateField = field;
                    break;
                }
            }

            if (dateField == null)
            {
                return;
            }

            //get the data source type from the QueryDateHelper by running a series of test queries against the dateField
            //
            QueryDateHelper.GetDataSource(QueryProperties.SubLayerDescription.Url, QueryProperties.SubLayerDescription.RequiresProxy, dateField, (object sender, DataSourceEventArgs e) =>
            {
                //query succeeded -> cache the datasource so the correctly formatted dates can be
                //generated when the expression is created
                //
                if (_dataSource == null)
                {
                    _dataSource = e.DataSource;
                }
                else
                {
                    //if data source has already been set check if this one has higher priority
                    //if yes - replace
                    //
                    List <string> supportedDS = new List <string>(QueryDateHelper.SupportedDataSources);
                    if (supportedDS.IndexOf(e.DataSource) < supportedDS.IndexOf(_dataSource))
                    {
                        _dataSource = e.DataSource;
                    }
                }

                ExpressionDatePickerButton.IsEnabled = true;
            });
        }
        /// <summary>
        /// Initializes the Data tab with a sample view of attributes of the layer.
        /// </summary>
        private void SetupPreview()
        {
            if (FeatureLayer == null)
            {
                return;
            }
            QueryTask qT = new QueryTask(FeatureLayer.Url);

            qT.ProxyURL = FeatureLayer.ProxyUrl;

            ESRI.ArcGIS.Client.Tasks.Query q = new ESRI.ArcGIS.Client.Tasks.Query();
            foreach (var field in QueryProperties.SubLayerDescription.Fields)
            {
                q.OutFields.Add(field.Name);
            }

            q.Where          = "1=1";    //query for features in the layer, todo: any way to limit the number of features returned?
            q.ReturnGeometry = false;

            EventHandler <ESRI.ArcGIS.Client.Tasks.QueryEventArgs> completedHandler = null;
            EventHandler <TaskFailedEventArgs> failedHandler = null;

            completedHandler = (object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs e) =>
            {
                PreviewDataGrid.Columns.Clear();
                if (e.FeatureSet == null || e.FeatureSet.Features == null || e.FeatureSet.Features.Count == 0)
                {
                    return;
                }

                //set up the columns of the table
                //if a field does not exist in the layer description don't add it to the table
                //this is the case for the geometry field
                //
                List <string> columns = new List <string>();
                foreach (string key in e.FeatureSet.Features[0].Attributes.Keys)
                {
                    if (GetField(key) != null)
                    {
                        columns.Add(key);
                    }
                }

                int   count = 0;
                Table table = new Table(columns.ToArray());
                foreach (Graphic feature in e.FeatureSet)
                {
                    List <object> cells = new List <object>();
                    foreach (var attribute in feature.Attributes)
                    {
                        SubLayerField field = GetField(attribute.Key);
                        if (field == null)
                        {
                            continue;
                        }

                        if (field.AttributeDomain != null && field.AttributeDomain.Type == "codedValue" && attribute.Value != null)
                        {
                            cells.Add(field.AttributeDomain[attribute.Value]);
                        }
                        else
                        {
                            //if the field value is a date in milliseconds format it to a user readable date
                            //
                            string formattedDateString = null;
                            if (field.Type == "esriFieldTypeDate" && attribute.Value != null && attribute.Value.ToString().TryParseToDateString(out formattedDateString))
                            {
                                cells.Add(formattedDateString);
                            }
                            else
                            {
                                cells.Add(attribute.Value);
                            }
                        }
                    }

                    table.Rows.Add(new Row(cells.ToArray()));

                    count++;
                    if (count == 25)
                    {
                        break;
                    }
                }

                //initialize the DataGrid columns
                //
                foreach (DataGridTextColumn column in table.Columns)
                {
                    column.CanUserSort = true;
                    PreviewDataGrid.Columns.Add(column);
                }

                //setting the table as the DataContext of the DataGrid initializes the rows via binding
                //
                PreviewDataGrid.DataContext = table;
                PreviewDataGrid.UpdateLayout();
                if (table.Rows.Count > 0 && PreviewDataGrid.Columns.Count > 0)
                {
                    PreviewDataGrid.ScrollIntoView(table.Rows[0].Cells[0], PreviewDataGrid.Columns[0]);
                }
                DataPreviewProgressIndicator.Visibility = Visibility.Collapsed;
            };

            failedHandler = ((object sender, TaskFailedEventArgs e) =>
            {
                FailedPreviewTextBlock.Visibility = Visibility.Visible;
                DataPreviewProgressIndicator.Visibility = Visibility.Collapsed;
            });

            qT.ExecuteCompleted += completedHandler;
            qT.Failed           += failedHandler;

            //execute the query
            //
            qT.ExecuteAsync(q);
        }
    /// <summary>
    /// Runs a test query against the specified date field to determine the type of data source.
    /// </summary>
    private static void QueryDate(string dataSetUrl, bool useProxy, SubLayerField dateField, string dataSource, EventHandler<DataSourceEventArgs> callback)
    {
      DateTime testDate = new DateTime(1977, 12, 01, 0, 0, 0, 0);

      QueryTask qT = new QueryTask(dataSetUrl);
      if (useProxy)
        qT.ProxyURL = ArcGISOnlineEnvironment.ConfigurationUrls.ProxyServerEncoded;

      ESRI.ArcGIS.Client.Tasks.Query q = new ESRI.ArcGIS.Client.Tasks.Query();
      q.OutFields.Add(dateField.Name);
      q.Where = dateField.Name + " = " + Format(testDate, dataSource);
      q.ReturnGeometry = false;

      EventHandler<ESRI.ArcGIS.Client.Tasks.QueryEventArgs> completedHandler = null;
			completedHandler = (object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs e) =>
      {
        callback(null, new DataSourceEventArgs() { DataSource = dataSource });
      };

      qT.ExecuteCompleted += completedHandler;

      //execute the query
      //
      qT.ExecuteAsync(q);
    }
 /// <summary>
 /// Determines the data source type asynchronously from a date field by running a series of test queries against it.
 /// </summary>
 /// <remarks>
 /// If a test query succeeds the data source type is reported back to the client via the callback. It is possible that
 /// multiple queries succeed so the client is called back multiple times.
 /// </remarks>
 /// <param name="dataSetUrl">The data set that contains the dateField.</param>
 /// <param name="dateField">A date field used to determine the data source type.</param>
 /// <param name="callback">A event handler that is called back when a test query succeeds. Multiple callbacks are possible.</param>
 public static void GetDataSource(string dataSetUrl, bool useProxy, SubLayerField dateField, EventHandler<DataSourceEventArgs> callback)
 {
   foreach (string dataSource in SupportedDataSources)
     QueryDate(dataSetUrl, useProxy, dateField, dataSource, callback);
 }