This application shows a simple way to use the ArcGIS Runtime SDK for WPF within a
console application. It uses only synchronous methods and no async
callbacks. This ensures there's just one thread of execution which
is typical of console apps and keeps the flow simple. The Local
Server and local Services can be started synchronously, then using
synchronous methods on tasks like Query ensure the results are
retured to the calling thread.
<UserControlx:Class="ArcGISWPFSDK.ConsoleHost"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"mc:Ignorable="d"d:DesignHeight="300"d:DesignWidth="500"><Grid><!--
See the CodeBehind for the code required for console application
This XAML is not required for a console application.
--><ButtonContent="Start Console Sample"Height="41"HorizontalAlignment="Left"Margin="12,12,0,0"Name="ButtonStartConsole"Click="ButtonStartConsole_Click"VerticalAlignment="Top"Width="238"/><TextBoxName="TextBoxConsole"Background="Black"Height="195"FontFamily="Lucida Console"Foreground="White"FontSize="12"VerticalScrollBarVisibility="Visible"HorizontalAlignment="Left"Margin="12,59,0,0"VerticalAlignment="Top"Width="476"IsReadOnly="True"/></Grid></UserControl>
using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using ESRI.ArcGIS.Client.Local;
using ESRI.ArcGIS.Client.Tasks;
using ESRI.ArcGIS.Client;
using System.IO;
using System.Windows.Threading;
namespace ArcGISWPFSDK
{
// This class is an example of a typical console application.class ConsoleProgram
{
// The console application entry point.internalstaticvoid Main(string[] args)
{
// Start a local map service using a map package
Console.WriteLine("Local Map Service starting ...");
LocalMapService localMapService = new LocalMapService(@"..\Data\MPKs\USCitiesStates.mpk");
// Start the local service synchronously
localMapService.Start();
// Query some data from the first layer in the map service
QueryTask queryTask = new QueryTask(localMapService.MapLayers[0].Url);
var q = new Query() { Where = "POP2000>1000000" };
q.OutFields.Add("*");
q.ReturnGeometry = false;
Console.WriteLine("Querying US cities with population more than 1 million");
// Execute a Query synchronously
FeatureSet featureSet = queryTask.Execute(q);
if (featureSet != null)
{
// Output some results ...
Console.WriteLine("Found " + featureSet.Features.Count + " cities.");
foreach (Graphic record in featureSet)
{
int pop = (int)record.Attributes["POP2000"];
Console.WriteLine(record.Attributes["AREANAME"] + " population " + pop.ToString("N0"));
}
}
else
Console.WriteLine("No cities found.");
// Synchronously stop the LocalMapService
localMapService.Stop();
Console.WriteLine("Sample complete.");
}
}
// This class is not required for a console application. Its hosts the sample // console app into the xaml application to be able to demo this code.publicpartialclass ConsoleHost : UserControl
{
// This class is used to capture console output so we can display it in a textboxpublicclass TextBoxStreamWriter : TextWriter
{
TextBox _textBox = null;
public TextBoxStreamWriter(TextBox output)
{
_textBox = output;
}
publicoverridevoid Write(char value)
{
base.Write(value);
_textBox.AppendText(value.ToString());
// This causes the WPF UI to update so we can see the console output
_textBox.Dispatcher.Invoke((Action)(() => { }), DispatcherPriority.Render);
}
publicoverride Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}
public ConsoleHost()
{
InitializeComponent();
}
publicvoid ButtonStartConsole_Click(object sender, RoutedEventArgs e)
{
// Capture the output to the console
TextBoxConsole.Text = string.Empty;
ButtonStartConsole.IsEnabled = false;
TextBoxStreamWriter textBoxStreamWriter = new TextBoxStreamWriter(TextBoxConsole);
TextWriter oldStream = Console.Out;
Console.SetOut(textBoxStreamWriter);
// run the sample
ConsoleProgram.Main(null);
// restore the old sample
Console.SetOut(oldStream);
textBoxStreamWriter.Close();
textBoxStreamWriter.Dispose();
ButtonStartConsole.IsEnabled = true;
}
}
}
Imports System.Text
Imports System.Windows
Imports System.Windows.Controls
Imports ESRI.ArcGIS.Client.Local
Imports ESRI.ArcGIS.Client.Tasks
Imports ESRI.ArcGIS.Client
Imports System.IO
Imports System.Windows.Threading
Namespace ArcGISWPFSDK
' This class is an example of a typical console application.Class ConsoleProgram
' The console application entry point.FriendSharedSub Main(args AsString())
' Start a local map service using a map package
Console.WriteLine("Local Map Service starting ...")
Dim localMapService AsNew LocalMapService("..\Data\MPKs\USCitiesStates.mpk")
' Start the local service synchronously
localMapService.Start()
' Query some data from the first layer in the map serviceDim queryTask AsNew QueryTask(localMapService.MapLayers(0).Url)
Dim q AsNew Query() With { _
.Where = "POP2000>1000000" _
}
q.OutFields.Add("*")
q.ReturnGeometry = False
Console.WriteLine("Querying US cities with population more than 1 million")
' Execute a Query synchronouslyDim featureSet As FeatureSet = queryTask.Execute(q)
If featureSet IsNotNothingThen' Output some results ...
Console.WriteLine("Found " & featureSet.Features.Count & " cities.")
ForEach record As Graphic In featureSet
Dim pop AsInteger = CInt(record.Attributes("POP2000"))
Console.WriteLine(Convert.ToString(record.Attributes("AREANAME")) & " population " & pop.ToString("N0"))
NextElse
Console.WriteLine("No cities found.")
EndIf'Synchronously Stop the LocalMapService
localMapService.Stop()
Console.WriteLine("Sample complete.")
EndSubEndClass' This class is not required for a console application. Its hosts the sample ' console app into the xaml application to be able to demo this code.PartialPublicClass ConsoleHost
Inherits UserControl
' This class is used to capture console output so we can display it in a textboxPublicClass TextBoxStreamWriter
Inherits TextWriter
Private _textBox As TextBox = NothingPublicSubNew(output As TextBox)
_textBox = output
EndSubPublicOverridesSub Write(value AsChar)
MyBase.Write(value)
_textBox.AppendText(value.ToString())
' This causes the WPF UI to update so we can see the console output
_textBox.Dispatcher.Invoke(DirectCast(Function()
EndFunction, Action), DispatcherPriority.Render)
EndSubPublicOverridesReadOnlyProperty Encoding() As Encoding
GetReturn System.Text.Encoding.UTF8
EndGetEndPropertyEndClassPublicSubNew()
InitializeComponent()
EndSubPublicSub ButtonStartConsole_Click(sender AsObject, e As RoutedEventArgs)
' Capture the output to the console
TextBoxConsole.Text = String.Empty
ButtonStartConsole.IsEnabled = FalseDim textBoxStreamWriter AsNew TextBoxStreamWriter(TextBoxConsole)
Dim oldStream As TextWriter = Console.Out
Console.SetOut(textBoxStreamWriter)
' run the sample
ConsoleProgram.Main(Nothing)
' restore the old sample
Console.SetOut(oldStream)
textBoxStreamWriter.Close()
textBoxStreamWriter.Dispose()
ButtonStartConsole.IsEnabled = TrueEndSubEndClassEndNamespace