Visual Basic (Declaration) | |
---|---|
Public Sub Select() |
C# | |
---|---|
public void Select() |
By default a Graphic is not selected (i.e. Selected = False). If a Graphic is selected the Selected Property will be True.
The Symbol of a Graphic does not automatically change according to the Graphic’s Selected status. Custom code in either the XAML or code-behind is required to change the Symbol of the Graphic when the Graphic’s Selected status changes.
There are several ways to select a Graphic using visual interaction with the Map Control; some examples are:
- As a result of a Geometry service (see the code example in this document – this example uses the VisualStateManager to switch selected symbologies)
- Via the XAML System.Windows.VisualStateManager Graphic.Selected Property) (see another VisualStateManager code example in the Graphic.Selected Property). Note: The VisualStateManager Class was newly added in the .NET Framework v4.0. If you are running the .NET Framework v3.5 then you can download and Reference the WPFToolkit on Codeplex to take advantage of the VisualStateManager Class.
- By iterating over the GraphicsCollection (see the code example in the Graphic.UnSelect Method)
- Using the Editor Class (see the interactive SDK sample Edit Tools - Auto Save)
How to use:
Click on the Polygon Graphics with the left mouse button while holding down the ALT key in the Map Control to change the Selection value and Symbology. A GeometryService.IntersectAsync is used to see if the MapPoint where the mouse click occurred falls within any polygon Graphics in the GraphicsLayer. If there is an intersection the Graphics is selected. The XAML VisualStateManager in the FillSymbol's ControlTemplate performs the work for swapping the symbology for selected Graphics.
The XAML code in this example is used in conjunction with the code-behind (C# or VB.NET) to demonstrate the functionality.
The following screen shot corresponds to the code example in this page.
XAML | Copy Code |
---|---|
<Grid x:Name="LayoutRoot"> <!-- Define a FillSymbol in the Resources section of the XAML file. The FillSymbol uses a ControlTemplate to define two VisualStateGroups which automatically switch symbology on the GraphicsLayer depending on whether individual Graphic objects are selected or not. Also define a SpatialReference for using best practices when adding Graphics to the GraphicsLayer. --> <Grid.Resources> <esriSymbols:FillSymbol x:Key="SelectFillSymbol"> <esriSymbols:FillSymbol.ControlTemplate> <ControlTemplate> <!-- Provide the default look of the FillSymbol for the polygon Graphic (a solid blue fill with black edges). --> <Path x:Name="Element" Stroke="Black" StrokeStartLineCap="Round" StrokeThickness="5" StrokeLineJoin="Round" StrokeEndLineCap="Round" Fill="Blue"> <!-- Learn more about the VisualStateManager in the MSDN document: http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate(v=VS.95).aspx Note: The VisualStateManager Class was newly added in the .NET Framework v4.0. If you are running the .NET Framework v3.5 then you can download and Reference the WPFToolkit on Codeplex (http://wpf.codeplex.com) to take advantage of the VisualStateManager Class. --> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="SelectionStates"> <!-- By specifying an empty Unselected state, unselecting the graphic will set the values back to their original value. The use of a Duration and Storyboard provides a smooth transition back. Note that it take 0 seconds for the Graphic to be selected and .5 seconds to go back to the original state. --> <VisualState x:Name="Unselected" > <Storyboard> <!-- Note how the To="Blue" Attribute matches the default Fill Attribute value of the Path x:Name="Element" for defining the Polygon's Symbology. --> <ColorAnimation Storyboard.TargetName="Element" To="Blue" Duration="00:00:00.50" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"/> </Storyboard> </VisualState> <VisualState x:Name="Selected"> <Storyboard> <!-- The To="Yellow" Attribute will become the Fill Atrribute value for the Selected state of the Path x:Name="Element" for defining the Polygon's Symbology. --> <ColorAnimation Storyboard.TargetName="Element" To="Yellow" Duration="00:00:00.00" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"/> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </Path> </ControlTemplate> </esriSymbols:FillSymbol.ControlTemplate> </esriSymbols:FillSymbol> <!-- Define a SpatialReference object that has the same WKID as the ArcGISTiledMapServiceLayer in the Map. This will allow for the Graphics in the GraphicsLayer to line up properly. --> <esri:SpatialReference x:Key="theSpatialReference" WKID="4326"/> </Grid.Resources> <!-- Add a Map control with an ArcGISTiledMapServiceLayer and a GraphicsLayer. The GraphicsLayer will contain several Graphics based upon Polygon geometries and using the SelectFillSymbol for the symbolization. By default the Graphics are not selected. The MouseClick Event on the Map has been specified to wire-up code-behind functionality. --> <esri:Map Background="White" HorizontalAlignment="Left" Margin="12,150,0,0" Name="Map1" VerticalAlignment="Top" Height="318" Width="483" MouseClick="Map1_MouseClick"> <esri:ArcGISTiledMapServiceLayer ID="PhysicalTiledLayer" Url="http://services.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/> <esri:GraphicsLayer ID="MyGraphicsLayer" > <esri:GraphicsLayer.Graphics> <!-- Define several Polygon based Graphics using the StaticResources for the Symbol and SpatialReference. --> <esri:Graphic Symbol="{StaticResource SelectFillSymbol}"> <esri:Polygon SpatialReference="{StaticResource theSpatialReference}"> <esri:Polygon.Rings> <esri:PointCollection> <esri:MapPoint X="15" Y="-20" /> <esri:MapPoint X="28" Y="-7" /> <esri:MapPoint X="53" Y="-17" /> <esri:MapPoint X="42" Y="-43" /> <esri:MapPoint X="13" Y="-63" /> <esri:MapPoint X="17" Y="-46" /> <esri:MapPoint X="15" Y="-20" /> </esri:PointCollection> </esri:Polygon.Rings> </esri:Polygon> </esri:Graphic> <esri:Graphic Symbol="{StaticResource SelectFillSymbol}"> <esri:Polygon SpatialReference="{StaticResource theSpatialReference}"> <esri:Polygon.Rings> <esri:PointCollection> <esri:MapPoint X="12" Y="20" /> <esri:MapPoint X="32" Y="17" /> <esri:MapPoint X="67" Y="35" /> <esri:MapPoint X="11" Y="46" /> <esri:MapPoint X="12" Y="20" /> </esri:PointCollection> </esri:Polygon.Rings> </esri:Polygon> </esri:Graphic> <esri:Graphic Symbol="{StaticResource SelectFillSymbol}"> <esri:Polygon SpatialReference="{StaticResource theSpatialReference}"> <esri:Polygon.Rings> <esri:PointCollection> <esri:MapPoint X="15" Y="17" /> <esri:MapPoint X="50" Y="5" /> <esri:MapPoint X="-40" Y="8" /> <esri:MapPoint X="-18" Y="18" /> <esri:MapPoint X="15" Y="17" /> </esri:PointCollection> </esri:Polygon.Rings> </esri:Polygon> </esri:Graphic> </esri:GraphicsLayer.Graphics> </esri:GraphicsLayer> </esri:Map> <!-- Provide the instructions on how to use the sample code. --> <TextBlock Height="132" HorizontalAlignment="Left" Name="TextBlock1" VerticalAlignment="Top" Width="578" TextWrapping="Wrap" Margin="12,12,0,0" Text="Click on the Polygon Graphics with the left mouse button while holding down the Alt key in the Map Control to change the Selection value and Symbology. A GeometryService.IntersectAsync is used to see if the MapPoint where the mouse click occurred falls within any polygon Graphics in the GraphicsLayer. If there is an intersection the Graphics is selected. The XAML VisualStateManager in the FillSymbol's ControlTemplate performs the work for swapping the symbology for selected Graphics." /> </Grid> |
C# | Copy Code |
---|---|
// Note: The over use of Global variables is never a good programming practice. But in the case of // Asynchronous programming it sometimes becomes an evil necessity. The following three Global // (aka. Member) variables are used as part of the events in Asynchronous web service calls to // ArcGIS Server. private ESRI.ArcGIS.Client.Tasks.GeometryService _GeometryService; private ESRI.ArcGIS.Client.Geometry.Geometry _aMapPointGeometry; private ESRI.ArcGIS.Client.GraphicCollection _theGraphicsCollection; private void Map1_MouseClick(object sender, ESRI.ArcGIS.Client.Map.MouseEventArgs e) { // This event fires when the user left clicks with the mouse in the Map control. If the user is holding // down the Alt key when the mouse is clicked: (1) a MapPoint is created from the mouse click location, // (2) the GraphicsLayer is retrieved from XAML, (3) the Asynchronous events are wired-up, and (4) the // first Asynchronous event is fired. If a user clicks over a Graphic it will be selected/unselected. // Get the ModifierKeys that are currently depressed (options include: None, Alt, Control, Shift, // Windows, and Apple). ModifierKeys theKey = Keyboard.Modifiers; // Check to ensure that only the Alt key is being depressed. if (theKey == ModifierKeys.Alt) { // Get the current Map Resolution. double currentResolution = Map1.Resolution; // e.MapPoint is where the user clicked on the Map. Create a MapPoint and get its Geometry. ESRI.ArcGIS.Client.Geometry.MapPoint aMapPoint = e.MapPoint; _aMapPointGeometry = (ESRI.ArcGIS.Client.Geometry.Geometry)aMapPoint; // Obtain the GraphicsLayer that was defined in XAML. ESRI.ArcGIS.Client.GraphicsLayer theGraphicsLayer = null; theGraphicsLayer = (ESRI.ArcGIS.Client.GraphicsLayer)(Map1.Layers["MyGraphicsLayer"]); _theGraphicsCollection = theGraphicsLayer.Graphics; // Define a GeometryService and add the Asynchronous event handlers. _GeometryService = new ESRI.ArcGIS.Client.Tasks.GeometryService("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"); _GeometryService.SimplifyCompleted += GeometryService_SimplifyCompleted; _GeometryService.IntersectCompleted += GeometryService_IntersectCompleted; _GeometryService.Failed += GeometryService_Failed; // Call simplify operation to correct orientation of rings in a polygon (clockwise = ring, // counterclockwise = hole). _GeometryService.SimplifyAsync(_theGraphicsCollection); // Special Note: // When you call a GeometryService, the Geometry of the objects being passed into the various // functions must have a valid SpatialReference set or else you wil get an Argument Exception // error. In this code example the SpatialReference for the Graphics in the GraphicsLayer was // define in XAML. The following is example syntax of the error message that could result if // your Graphics do not have a valid SpatialReference defined: // "Value cannot be null. Parameter(Name) : Geometry.SpatialReference()" } } private void GeometryService_SimplifyCompleted(object sender, ESRI.ArcGIS.Client.Tasks.GraphicsEventArgs e) { // This event fires as a result of altering the given geometries (polygons in this case) to make // their definitions topologically legal with respect to their geometry type. // Now call the IntersectAsync Geometry service which will determine if the MapPoint that was // created from the user mouse click falls inside of any Polygon Graphics in the GraphicsCollection // of the GraphicsLayer. _GeometryService.IntersectAsync(_theGraphicsCollection, _aMapPointGeometry); } private void GeometryService_IntersectCompleted(object sender, ESRI.ArcGIS.Client.Tasks.GraphicsEventArgs e) { // This event constructs the set-theoretic intersection between an collection of geometries and // another geometry. // Loop through all of the returned Graphics. e.Results is a List(Of Graphics). for (int i = 0; i <= (e.Results.Count - 1); i++) { // Only process Graphics with a valid Extent (i.e. not empty). Only those Graphics that // not have a valid Extent are the ones where an Intersection has occured! if (e.Results[i].Geometry.Extent != null) { // Alternate between setting the Graphic's Select/UnSelected Methods to True/False // depending on where the user clicks it with the Alt + left mouse button. The // transitioning from one Symbol to another on the Graphic based upon its selected // state is exclusively handled in XAML using the VisualStateManager Class. if (_theGraphicsCollection[i].Selected == true) { _theGraphicsCollection[i].UnSelect(); } else if (_theGraphicsCollection[i].Selected == false) { _theGraphicsCollection[i].Select(); } } } } private void GeometryService_Failed(object sender, ESRI.ArcGIS.Client.Tasks.TaskFailedEventArgs args) { // This event is a catch all if something goes wrong with either of the GeometryService // Aysnchronous calls. MessageBox.Show("Geometry Service error: " + args.Error.Message); } |
VB.NET | Copy Code |
---|---|
' Note: The over use of Global variables is never a good programming practice. But in the case of ' Asynchronous programming it sometimes becomes an evil necessity. The following three Global ' (aka. Member) variables are used as part of the events in Asynchronous web service calls to ' ArcGIS Server. Private _GeometryService As ESRI.ArcGIS.Client.Tasks.GeometryService Private _aMapPointGeometry As ESRI.ArcGIS.Client.Geometry.Geometry Private _theGraphicsCollection As ESRI.ArcGIS.Client.GraphicCollection Private Sub Map1_MouseClick(ByVal sender As System.Object, ByVal e As ESRI.ArcGIS.Client.Map.MouseEventArgs) ' This event fires when the user left clicks with the mouse in the Map control. If the user is holding ' down the Alt key when the mouse is clicked: (1) a MapPoint is created from the mouse click location, ' (2) the GraphicsLayer is retrieved from XAML, (3) the Asynchronous events are wired-up, and (4) the ' first Asynchronous event is fired. If a user clicks over a Graphic it will be selected/unselected. ' Get the ModifierKeys that are currently depressed (options include: None, Alt, Control, Shift, ' Windows, and Apple). Dim theKey As ModifierKeys = Keyboard.Modifiers ' Check to ensure that only the Alt key is being depressed. If theKey = ModifierKeys.Alt Then ' Get the current Map Resolution. Dim currentResolution As Double = Map1.Resolution ' e.MapPoint is where the user clicked on the Map. Create a MapPoint and get its Geometry. Dim aMapPoint As ESRI.ArcGIS.Client.Geometry.MapPoint = e.MapPoint _aMapPointGeometry = CType(aMapPoint, ESRI.ArcGIS.Client.Geometry.Geometry) ' Obtain the GraphicsLayer that was defined in XAML. Dim theGraphicsLayer As ESRI.ArcGIS.Client.GraphicsLayer theGraphicsLayer = CType(Map1.Layers("MyGraphicsLayer"), ESRI.ArcGIS.Client.GraphicsLayer) _theGraphicsCollection = theGraphicsLayer.Graphics ' Define a GeometryService and add the Asynchronous event handlers. _GeometryService = New ESRI.ArcGIS.Client.Tasks.GeometryService("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer") AddHandler _GeometryService.SimplifyCompleted, AddressOf GeometryService_SimplifyCompleted AddHandler _GeometryService.IntersectCompleted, AddressOf GeometryService_IntersectCompleted AddHandler _GeometryService.Failed, AddressOf GeometryService_Failed ' Call simplify operation to correct orientation of rings in a polygon (clockwise = ring, ' counterclockwise = hole). _GeometryService.SimplifyAsync(_theGraphicsCollection) ' Special Note: ' When you call a GeometryService, the Geometry of the objects being passed into the various ' functions must have a valid SpatialReference set or else you wil get an Argument Exception ' error. In this code example the SpatialReference for the Graphics in the GraphicsLayer was ' define in XAML. The following is example syntax of the error message that could result if ' your Graphics do not have a valid SpatialReference defined: ' "Value cannot be null. Parameter(Name) : Geometry.SpatialReference()" End If End Sub Private Sub GeometryService_SimplifyCompleted(ByVal sender As Object, ByVal e As ESRI.ArcGIS.Client.Tasks.GraphicsEventArgs) ' This event fires as a result of altering the given geometries (polygons in this case) to make ' their definitions topologically legal with respect to their geometry type. ' Now call the IntersectAsync Geometry service which will determine if the MapPoint that was ' created from the user mouse click falls inside of any Polygon Graphics in the GraphicsCollection ' of the GraphicsLayer. _GeometryService.IntersectAsync(_theGraphicsCollection, _aMapPointGeometry) End Sub Private Sub GeometryService_IntersectCompleted(ByVal sender As Object, ByVal e As ESRI.ArcGIS.Client.Tasks.GraphicsEventArgs) ' This event constructs the set-theoretic intersection between an collection of geometries and ' another geometry. ' Loop through all of the returned Graphics. e.Results is a List(Of Graphics). For i As Integer = 0 To (e.Results.Count - 1) ' Only process Graphics with a valid Extent (i.e. not empty). Only those Graphics that ' not have a valid Extent are the ones where an Intersection has occured! If e.Results.Item(i).Geometry.Extent IsNot Nothing Then ' Alternate between setting the Graphic's Select/UnSelected Methods to True/False ' depending on where the user clicks it with the Alt + left mouse button. The ' transitioning from one Symbol to another on the Graphic based upon its selected ' state is exclusively handled in XAML using the VisualStateManager Class. If _theGraphicsCollection.Item(i).Selected = True Then _theGraphicsCollection.Item(i).UnSelect() ElseIf _theGraphicsCollection.Item(i).Selected = False Then _theGraphicsCollection.Item(i).Select() End If End If Next End Sub Private Sub GeometryService_Failed(ByVal sender As Object, ByVal args As ESRI.ArcGIS.Client.Tasks.TaskFailedEventArgs) ' This event is a catch all if something goes wrong with either of the GeometryService ' Aysnchronous calls. MessageBox.Show("Geometry Service error: " + args.Error.Message) End Sub |
Target Platforms: Windows XP Professional, Windows Server 2003 family, Windows Vista, Windows Server 2008 family, Windows 7, Windows 8