[mapguide-commits] r6609 - in trunk/MgDev/Desktop: MapViewer MapViewer/Properties MapViewerTest

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Thu May 3 10:38:06 EDT 2012


Author: jng
Date: 2012-05-03 07:38:06 -0700 (Thu, 03 May 2012)
New Revision: 6609

Added:
   trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.Designer.cs
   trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs
   trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.resx
   trunk/MgDev/Desktop/MapViewer/MgComponent.cs
   trunk/MgDev/Desktop/MapViewer/MgControlImpl.cs
   trunk/MgDev/Desktop/MapViewer/MgInvokeComponent.cs
   trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.Designer.cs
   trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.cs
   trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.resx
   trunk/MgDev/Desktop/MapViewer/MgMeasureControl.cs
   trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.Designer.cs
   trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.cs
   trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.resx
Removed:
   trunk/MgDev/Desktop/MapViewer/MgBufferControl.Designer.cs
   trunk/MgDev/Desktop/MapViewer/MgBufferControl.resx
   trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.Designer.cs
   trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.cs
   trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.resx
   trunk/MgDev/Desktop/MapViewer/MgQueryControl.Designer.cs
   trunk/MgDev/Desktop/MapViewer/MgQueryControl.resx
Modified:
   trunk/MgDev/Desktop/MapViewer/MapViewer.Net40.csproj
   trunk/MgDev/Desktop/MapViewer/MapViewer.csproj
   trunk/MgDev/Desktop/MapViewer/MgBufferControl.cs
   trunk/MgDev/Desktop/MapViewer/MgQueryControl.cs
   trunk/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs
   trunk/MgDev/Desktop/MapViewer/Properties/Resources.resx
   trunk/MgDev/Desktop/MapViewerTest/Form1.Designer.cs
   trunk/MgDev/Desktop/MapViewerTest/Form1.cs
   trunk/MgDev/Desktop/MapViewerTest/Form1.resx
   trunk/MgDev/Desktop/MapViewerTest/Program.cs
Log:
Merge in r6607 and r6608

Modified: trunk/MgDev/Desktop/MapViewer/MapViewer.Net40.csproj
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MapViewer.Net40.csproj	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/MapViewer.Net40.csproj	2012-05-03 14:38:06 UTC (rev 6609)
@@ -91,14 +91,32 @@
     <Compile Include="IMapStatusBar.cs" />
     <Compile Include="IPropertyPane.cs" />
     <Compile Include="MgBufferControl.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="MgBufferControlImpl.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="MgBufferControl.Designer.cs">
-      <DependentUpon>MgBufferControl.cs</DependentUpon>
+    <Compile Include="MgBufferControlImpl.Designer.cs">
+      <DependentUpon>MgBufferControlImpl.cs</DependentUpon>
     </Compile>
+    <Compile Include="MgComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="MgControlImpl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
     <Compile Include="MgDefaultToolbar.cs">
       <SubType>Component</SubType>
     </Compile>
+    <Compile Include="MgInvokeComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="MgLineMeasureControlImpl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="MgLineMeasureControlImpl.Designer.cs">
+      <DependentUpon>MgLineMeasureControlImpl.cs</DependentUpon>
+    </Compile>
     <Compile Include="MgMapViewer.cs">
       <SubType>Component</SubType>
     </Compile>
@@ -110,12 +128,9 @@
       <DependentUpon>MgLegend.cs</DependentUpon>
     </Compile>
     <Compile Include="MgMapViewerProvider.cs" />
-    <Compile Include="MgLineMeasureControl.cs">
-      <SubType>UserControl</SubType>
+    <Compile Include="MgMeasureControl.cs">
+      <SubType>Component</SubType>
     </Compile>
-    <Compile Include="MgLineMeasureControl.Designer.cs">
-      <DependentUpon>MgLineMeasureControl.cs</DependentUpon>
-    </Compile>
     <Compile Include="MgPropertyPane.cs">
       <SubType>UserControl</SubType>
     </Compile>
@@ -123,10 +138,13 @@
       <DependentUpon>MgPropertyPane.cs</DependentUpon>
     </Compile>
     <Compile Include="MgQueryControl.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="MgQueryControlImpl.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="MgQueryControl.Designer.cs">
-      <DependentUpon>MgQueryControl.cs</DependentUpon>
+    <Compile Include="MgQueryControlImpl.Designer.cs">
+      <DependentUpon>MgQueryControlImpl.cs</DependentUpon>
     </Compile>
     <Compile Include="MgQueryResultsDialog.cs">
       <SubType>Form</SubType>
@@ -148,20 +166,20 @@
       <Generator>ResXFileCodeGenerator</Generator>
       <LastGenOutput>Debug.Designer.cs</LastGenOutput>
     </EmbeddedResource>
-    <EmbeddedResource Include="MgBufferControl.resx">
-      <DependentUpon>MgBufferControl.cs</DependentUpon>
+    <EmbeddedResource Include="MgBufferControlImpl.resx">
+      <DependentUpon>MgBufferControlImpl.cs</DependentUpon>
     </EmbeddedResource>
     <EmbeddedResource Include="MgLegend.resx">
       <DependentUpon>MgLegend.cs</DependentUpon>
     </EmbeddedResource>
-    <EmbeddedResource Include="MgLineMeasureControl.resx">
-      <DependentUpon>MgLineMeasureControl.cs</DependentUpon>
+    <EmbeddedResource Include="MgLineMeasureControlImpl.resx">
+      <DependentUpon>MgLineMeasureControlImpl.cs</DependentUpon>
     </EmbeddedResource>
     <EmbeddedResource Include="MgPropertyPane.resx">
       <DependentUpon>MgPropertyPane.cs</DependentUpon>
     </EmbeddedResource>
-    <EmbeddedResource Include="MgQueryControl.resx">
-      <DependentUpon>MgQueryControl.cs</DependentUpon>
+    <EmbeddedResource Include="MgQueryControlImpl.resx">
+      <DependentUpon>MgQueryControlImpl.cs</DependentUpon>
     </EmbeddedResource>
     <EmbeddedResource Include="MgQueryResultsDialog.resx">
       <DependentUpon>MgQueryResultsDialog.cs</DependentUpon>

Modified: trunk/MgDev/Desktop/MapViewer/MapViewer.csproj
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MapViewer.csproj	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/MapViewer.csproj	2012-05-03 14:38:06 UTC (rev 6609)
@@ -69,20 +69,32 @@
     <Compile Include="IMapViewerComponent.cs" />
     <Compile Include="IMapStatusBar.cs" />
     <Compile Include="IPropertyPane.cs" />
+    <Compile Include="MgComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
     <Compile Include="MgBufferControl.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="MgBufferControlImpl.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="MgBufferControl.Designer.cs">
-      <DependentUpon>MgBufferControl.cs</DependentUpon>
+    <Compile Include="MgBufferControlImpl.Designer.cs">
+      <DependentUpon>MgBufferControlImpl.cs</DependentUpon>
     </Compile>
+    <Compile Include="MgControlImpl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
     <Compile Include="MgDefaultToolbar.cs">
       <SubType>Component</SubType>
     </Compile>
-    <Compile Include="MgLineMeasureControl.cs">
+    <Compile Include="MgInvokeComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="MgLineMeasureControlImpl.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="MgLineMeasureControl.Designer.cs">
-      <DependentUpon>MgLineMeasureControl.cs</DependentUpon>
+    <Compile Include="MgLineMeasureControlImpl.Designer.cs">
+      <DependentUpon>MgLineMeasureControlImpl.cs</DependentUpon>
     </Compile>
     <Compile Include="MgMapViewer.cs">
       <SubType>Component</SubType>
@@ -95,6 +107,9 @@
       <DependentUpon>MgLegend.cs</DependentUpon>
     </Compile>
     <Compile Include="MgMapViewerProvider.cs" />
+    <Compile Include="MgMeasureControl.cs">
+      <SubType>Component</SubType>
+    </Compile>
     <Compile Include="MgPropertyPane.cs">
       <SubType>UserControl</SubType>
     </Compile>
@@ -102,10 +117,13 @@
       <DependentUpon>MgPropertyPane.cs</DependentUpon>
     </Compile>
     <Compile Include="MgQueryControl.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="MgQueryControlImpl.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="MgQueryControl.Designer.cs">
-      <DependentUpon>MgQueryControl.cs</DependentUpon>
+    <Compile Include="MgQueryControlImpl.Designer.cs">
+      <DependentUpon>MgQueryControlImpl.cs</DependentUpon>
     </Compile>
     <Compile Include="MgQueryResultsDialog.cs">
       <SubType>Form</SubType>
@@ -127,20 +145,20 @@
       <Generator>ResXFileCodeGenerator</Generator>
       <LastGenOutput>Debug.Designer.cs</LastGenOutput>
     </EmbeddedResource>
-    <EmbeddedResource Include="MgBufferControl.resx">
-      <DependentUpon>MgBufferControl.cs</DependentUpon>
+    <EmbeddedResource Include="MgBufferControlImpl.resx">
+      <DependentUpon>MgBufferControlImpl.cs</DependentUpon>
     </EmbeddedResource>
     <EmbeddedResource Include="MgLegend.resx">
       <DependentUpon>MgLegend.cs</DependentUpon>
     </EmbeddedResource>
-    <EmbeddedResource Include="MgLineMeasureControl.resx">
-      <DependentUpon>MgLineMeasureControl.cs</DependentUpon>
+    <EmbeddedResource Include="MgLineMeasureControlImpl.resx">
+      <DependentUpon>MgLineMeasureControlImpl.cs</DependentUpon>
     </EmbeddedResource>
     <EmbeddedResource Include="MgPropertyPane.resx">
       <DependentUpon>MgPropertyPane.cs</DependentUpon>
     </EmbeddedResource>
-    <EmbeddedResource Include="MgQueryControl.resx">
-      <DependentUpon>MgQueryControl.cs</DependentUpon>
+    <EmbeddedResource Include="MgQueryControlImpl.resx">
+      <DependentUpon>MgQueryControlImpl.cs</DependentUpon>
     </EmbeddedResource>
     <EmbeddedResource Include="MgQueryResultsDialog.resx">
       <DependentUpon>MgQueryResultsDialog.cs</DependentUpon>

Deleted: trunk/MgDev/Desktop/MapViewer/MgBufferControl.Designer.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgBufferControl.Designer.cs	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/MgBufferControl.Designer.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -1,457 +0,0 @@
-namespace OSGeo.MapGuide.Viewer
-{
-    partial class MgBufferControl
-    {
-        /// <summary> 
-        /// Required designer variable.
-        /// </summary>
-        private System.ComponentModel.IContainer components = null;
-
-        /// <summary> 
-        /// Clean up any resources being used.
-        /// </summary>
-        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing && (components != null))
-            {
-                components.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-
-        #region Component Designer generated code
-
-        /// <summary> 
-        /// Required method for Designer support - do not modify 
-        /// the contents of this method with the code editor.
-        /// </summary>
-        private void InitializeComponent()
-        {
-            this.groupBox1 = new System.Windows.Forms.GroupBox();
-            this.lstLayers = new System.Windows.Forms.ListBox();
-            this.label2 = new System.Windows.Forms.Label();
-            this.cmbUnits = new System.Windows.Forms.ComboBox();
-            this.numBufferDistance = new System.Windows.Forms.NumericUpDown();
-            this.label1 = new System.Windows.Forms.Label();
-            this.lblSelectFeatures = new System.Windows.Forms.Label();
-            this.groupBox2 = new System.Windows.Forms.GroupBox();
-            this.btnFillBackColor = new System.Windows.Forms.Button();
-            this.pnlFillBackColor = new System.Windows.Forms.Panel();
-            this.label10 = new System.Windows.Forms.Label();
-            this.numFillTransparency = new System.Windows.Forms.NumericUpDown();
-            this.label5 = new System.Windows.Forms.Label();
-            this.btnFillColor = new System.Windows.Forms.Button();
-            this.pnlFillColor = new System.Windows.Forms.Panel();
-            this.label4 = new System.Windows.Forms.Label();
-            this.cmbFillPattern = new System.Windows.Forms.ComboBox();
-            this.label3 = new System.Windows.Forms.Label();
-            this.groupBox3 = new System.Windows.Forms.GroupBox();
-            this.numLineThickness = new System.Windows.Forms.NumericUpDown();
-            this.cmbBorderPattern = new System.Windows.Forms.ComboBox();
-            this.label6 = new System.Windows.Forms.Label();
-            this.label8 = new System.Windows.Forms.Label();
-            this.btnBorderColor = new System.Windows.Forms.Button();
-            this.label7 = new System.Windows.Forms.Label();
-            this.pnlBorderColor = new System.Windows.Forms.Panel();
-            this.btnCreate = new System.Windows.Forms.Button();
-            this.groupBox4 = new System.Windows.Forms.GroupBox();
-            this.chkMergeBuffers = new System.Windows.Forms.CheckBox();
-            this.txtBufferLayer = new System.Windows.Forms.TextBox();
-            this.label9 = new System.Windows.Forms.Label();
-            this.colorPicker = new System.Windows.Forms.ColorDialog();
-            this.groupBox1.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.numBufferDistance)).BeginInit();
-            this.groupBox2.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.numFillTransparency)).BeginInit();
-            this.groupBox3.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.numLineThickness)).BeginInit();
-            this.groupBox4.SuspendLayout();
-            this.SuspendLayout();
-            // 
-            // groupBox1
-            // 
-            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.groupBox1.Controls.Add(this.lstLayers);
-            this.groupBox1.Controls.Add(this.label2);
-            this.groupBox1.Controls.Add(this.cmbUnits);
-            this.groupBox1.Controls.Add(this.numBufferDistance);
-            this.groupBox1.Controls.Add(this.label1);
-            this.groupBox1.Controls.Add(this.lblSelectFeatures);
-            this.groupBox1.Location = new System.Drawing.Point(0, 0);
-            this.groupBox1.Name = "groupBox1";
-            this.groupBox1.Size = new System.Drawing.Size(232, 220);
-            this.groupBox1.TabIndex = 0;
-            this.groupBox1.TabStop = false;
-            this.groupBox1.Text = "Buffer Settings";
-            // 
-            // lstLayers
-            // 
-            this.lstLayers.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
-            | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.lstLayers.FormattingEnabled = true;
-            this.lstLayers.Location = new System.Drawing.Point(9, 126);
-            this.lstLayers.Name = "lstLayers";
-            this.lstLayers.Size = new System.Drawing.Size(206, 82);
-            this.lstLayers.TabIndex = 5;
-            // 
-            // label2
-            // 
-            this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(6, 101);
-            this.label2.Name = "label2";
-            this.label2.Size = new System.Drawing.Size(180, 13);
-            this.label2.TabIndex = 4;
-            this.label2.Text = "Includes the following layers in buffer";
-            // 
-            // cmbUnits
-            // 
-            this.cmbUnits.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.cmbUnits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-            this.cmbUnits.FormattingEnabled = true;
-            this.cmbUnits.Location = new System.Drawing.Point(105, 66);
-            this.cmbUnits.Name = "cmbUnits";
-            this.cmbUnits.Size = new System.Drawing.Size(110, 21);
-            this.cmbUnits.TabIndex = 3;
-            // 
-            // numBufferDistance
-            // 
-            this.numBufferDistance.Location = new System.Drawing.Point(9, 67);
-            this.numBufferDistance.Maximum = new decimal(new int[] {
-            100000,
-            0,
-            0,
-            0});
-            this.numBufferDistance.Minimum = new decimal(new int[] {
-            100000,
-            0,
-            0,
-            -2147483648});
-            this.numBufferDistance.Name = "numBufferDistance";
-            this.numBufferDistance.Size = new System.Drawing.Size(92, 20);
-            this.numBufferDistance.TabIndex = 2;
-            // 
-            // label1
-            // 
-            this.label1.AutoSize = true;
-            this.label1.Location = new System.Drawing.Point(6, 50);
-            this.label1.Name = "label1";
-            this.label1.Size = new System.Drawing.Size(126, 13);
-            this.label1.TabIndex = 1;
-            this.label1.Text = "Distance around features";
-            // 
-            // lblSelectFeatures
-            // 
-            this.lblSelectFeatures.BackColor = System.Drawing.Color.White;
-            this.lblSelectFeatures.ForeColor = System.Drawing.Color.Blue;
-            this.lblSelectFeatures.Location = new System.Drawing.Point(6, 16);
-            this.lblSelectFeatures.Name = "lblSelectFeatures";
-            this.lblSelectFeatures.Size = new System.Drawing.Size(209, 23);
-            this.lblSelectFeatures.TabIndex = 0;
-            this.lblSelectFeatures.Text = "Select Features on the Map first";
-            this.lblSelectFeatures.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
-            // 
-            // groupBox2
-            // 
-            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.groupBox2.Controls.Add(this.btnFillBackColor);
-            this.groupBox2.Controls.Add(this.pnlFillBackColor);
-            this.groupBox2.Controls.Add(this.label10);
-            this.groupBox2.Controls.Add(this.numFillTransparency);
-            this.groupBox2.Controls.Add(this.label5);
-            this.groupBox2.Controls.Add(this.btnFillColor);
-            this.groupBox2.Controls.Add(this.pnlFillColor);
-            this.groupBox2.Controls.Add(this.label4);
-            this.groupBox2.Controls.Add(this.cmbFillPattern);
-            this.groupBox2.Controls.Add(this.label3);
-            this.groupBox2.Location = new System.Drawing.Point(0, 220);
-            this.groupBox2.Name = "groupBox2";
-            this.groupBox2.Size = new System.Drawing.Size(232, 144);
-            this.groupBox2.TabIndex = 1;
-            this.groupBox2.TabStop = false;
-            this.groupBox2.Text = "Fill Style";
-            // 
-            // btnFillBackColor
-            // 
-            this.btnFillBackColor.Location = new System.Drawing.Point(183, 102);
-            this.btnFillBackColor.Name = "btnFillBackColor";
-            this.btnFillBackColor.Size = new System.Drawing.Size(32, 23);
-            this.btnFillBackColor.TabIndex = 9;
-            this.btnFillBackColor.Text = "...";
-            this.btnFillBackColor.UseVisualStyleBackColor = true;
-            this.btnFillBackColor.Click += new System.EventHandler(this.btnFillBackColor_Click);
-            // 
-            // pnlFillBackColor
-            // 
-            this.pnlFillBackColor.Location = new System.Drawing.Point(95, 103);
-            this.pnlFillBackColor.Name = "pnlFillBackColor";
-            this.pnlFillBackColor.Size = new System.Drawing.Size(82, 22);
-            this.pnlFillBackColor.TabIndex = 8;
-            // 
-            // label10
-            // 
-            this.label10.AutoSize = true;
-            this.label10.Location = new System.Drawing.Point(30, 107);
-            this.label10.Name = "label10";
-            this.label10.Size = new System.Drawing.Size(59, 13);
-            this.label10.TabIndex = 7;
-            this.label10.Text = "Back Color";
-            // 
-            // numFillTransparency
-            // 
-            this.numFillTransparency.Location = new System.Drawing.Point(95, 77);
-            this.numFillTransparency.Name = "numFillTransparency";
-            this.numFillTransparency.Size = new System.Drawing.Size(120, 20);
-            this.numFillTransparency.TabIndex = 6;
-            // 
-            // label5
-            // 
-            this.label5.AutoSize = true;
-            this.label5.Location = new System.Drawing.Point(17, 79);
-            this.label5.Name = "label5";
-            this.label5.Size = new System.Drawing.Size(72, 13);
-            this.label5.TabIndex = 5;
-            this.label5.Text = "Transparency";
-            // 
-            // btnFillColor
-            // 
-            this.btnFillColor.Location = new System.Drawing.Point(183, 48);
-            this.btnFillColor.Name = "btnFillColor";
-            this.btnFillColor.Size = new System.Drawing.Size(32, 23);
-            this.btnFillColor.TabIndex = 4;
-            this.btnFillColor.Text = "...";
-            this.btnFillColor.UseVisualStyleBackColor = true;
-            this.btnFillColor.Click += new System.EventHandler(this.btnFillColor_Click);
-            // 
-            // pnlFillColor
-            // 
-            this.pnlFillColor.Location = new System.Drawing.Point(95, 49);
-            this.pnlFillColor.Name = "pnlFillColor";
-            this.pnlFillColor.Size = new System.Drawing.Size(82, 22);
-            this.pnlFillColor.TabIndex = 3;
-            // 
-            // label4
-            // 
-            this.label4.AutoSize = true;
-            this.label4.Location = new System.Drawing.Point(34, 53);
-            this.label4.Name = "label4";
-            this.label4.Size = new System.Drawing.Size(55, 13);
-            this.label4.TabIndex = 2;
-            this.label4.Text = "Fore Color";
-            // 
-            // cmbFillPattern
-            // 
-            this.cmbFillPattern.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-            this.cmbFillPattern.FormattingEnabled = true;
-            this.cmbFillPattern.Location = new System.Drawing.Point(95, 23);
-            this.cmbFillPattern.Name = "cmbFillPattern";
-            this.cmbFillPattern.Size = new System.Drawing.Size(120, 21);
-            this.cmbFillPattern.TabIndex = 1;
-            // 
-            // label3
-            // 
-            this.label3.AutoSize = true;
-            this.label3.Location = new System.Drawing.Point(48, 26);
-            this.label3.Name = "label3";
-            this.label3.Size = new System.Drawing.Size(41, 13);
-            this.label3.TabIndex = 0;
-            this.label3.Text = "Pattern";
-            // 
-            // groupBox3
-            // 
-            this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.groupBox3.Controls.Add(this.numLineThickness);
-            this.groupBox3.Controls.Add(this.cmbBorderPattern);
-            this.groupBox3.Controls.Add(this.label6);
-            this.groupBox3.Controls.Add(this.label8);
-            this.groupBox3.Controls.Add(this.btnBorderColor);
-            this.groupBox3.Controls.Add(this.label7);
-            this.groupBox3.Controls.Add(this.pnlBorderColor);
-            this.groupBox3.Location = new System.Drawing.Point(0, 364);
-            this.groupBox3.Name = "groupBox3";
-            this.groupBox3.Size = new System.Drawing.Size(232, 100);
-            this.groupBox3.TabIndex = 2;
-            this.groupBox3.TabStop = false;
-            this.groupBox3.Text = "Border Style";
-            // 
-            // numLineThickness
-            // 
-            this.numLineThickness.Location = new System.Drawing.Point(95, 73);
-            this.numLineThickness.Name = "numLineThickness";
-            this.numLineThickness.Size = new System.Drawing.Size(120, 20);
-            this.numLineThickness.TabIndex = 13;
-            // 
-            // cmbBorderPattern
-            // 
-            this.cmbBorderPattern.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-            this.cmbBorderPattern.FormattingEnabled = true;
-            this.cmbBorderPattern.Location = new System.Drawing.Point(95, 19);
-            this.cmbBorderPattern.Name = "cmbBorderPattern";
-            this.cmbBorderPattern.Size = new System.Drawing.Size(120, 21);
-            this.cmbBorderPattern.TabIndex = 8;
-            // 
-            // label6
-            // 
-            this.label6.AutoSize = true;
-            this.label6.Location = new System.Drawing.Point(17, 75);
-            this.label6.Name = "label6";
-            this.label6.Size = new System.Drawing.Size(72, 13);
-            this.label6.TabIndex = 12;
-            this.label6.Text = "Transparency";
-            // 
-            // label8
-            // 
-            this.label8.AutoSize = true;
-            this.label8.Location = new System.Drawing.Point(48, 22);
-            this.label8.Name = "label8";
-            this.label8.Size = new System.Drawing.Size(41, 13);
-            this.label8.TabIndex = 7;
-            this.label8.Text = "Pattern";
-            // 
-            // btnBorderColor
-            // 
-            this.btnBorderColor.Location = new System.Drawing.Point(183, 44);
-            this.btnBorderColor.Name = "btnBorderColor";
-            this.btnBorderColor.Size = new System.Drawing.Size(32, 23);
-            this.btnBorderColor.TabIndex = 11;
-            this.btnBorderColor.Text = "...";
-            this.btnBorderColor.UseVisualStyleBackColor = true;
-            this.btnBorderColor.Click += new System.EventHandler(this.btnBorderColor_Click);
-            // 
-            // label7
-            // 
-            this.label7.AutoSize = true;
-            this.label7.Location = new System.Drawing.Point(58, 49);
-            this.label7.Name = "label7";
-            this.label7.Size = new System.Drawing.Size(31, 13);
-            this.label7.TabIndex = 9;
-            this.label7.Text = "Color";
-            // 
-            // pnlBorderColor
-            // 
-            this.pnlBorderColor.Location = new System.Drawing.Point(95, 45);
-            this.pnlBorderColor.Name = "pnlBorderColor";
-            this.pnlBorderColor.Size = new System.Drawing.Size(82, 22);
-            this.pnlBorderColor.TabIndex = 10;
-            // 
-            // btnCreate
-            // 
-            this.btnCreate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-            this.btnCreate.Location = new System.Drawing.Point(9, 567);
-            this.btnCreate.Name = "btnCreate";
-            this.btnCreate.Size = new System.Drawing.Size(98, 23);
-            this.btnCreate.TabIndex = 3;
-            this.btnCreate.Text = "Create Buffer";
-            this.btnCreate.UseVisualStyleBackColor = true;
-            this.btnCreate.Click += new System.EventHandler(this.btnCreate_Click);
-            // 
-            // groupBox4
-            // 
-            this.groupBox4.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
-            | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.groupBox4.Controls.Add(this.chkMergeBuffers);
-            this.groupBox4.Controls.Add(this.txtBufferLayer);
-            this.groupBox4.Controls.Add(this.label9);
-            this.groupBox4.Location = new System.Drawing.Point(0, 464);
-            this.groupBox4.Name = "groupBox4";
-            this.groupBox4.Size = new System.Drawing.Size(232, 97);
-            this.groupBox4.TabIndex = 4;
-            this.groupBox4.TabStop = false;
-            this.groupBox4.Text = "Other";
-            // 
-            // chkMergeBuffers
-            // 
-            this.chkMergeBuffers.AutoSize = true;
-            this.chkMergeBuffers.Checked = true;
-            this.chkMergeBuffers.CheckState = System.Windows.Forms.CheckState.Checked;
-            this.chkMergeBuffers.Location = new System.Drawing.Point(12, 69);
-            this.chkMergeBuffers.Name = "chkMergeBuffers";
-            this.chkMergeBuffers.Size = new System.Drawing.Size(117, 17);
-            this.chkMergeBuffers.TabIndex = 2;
-            this.chkMergeBuffers.Text = "Merge Buffer Areas";
-            this.chkMergeBuffers.UseVisualStyleBackColor = true;
-            // 
-            // txtBufferLayer
-            // 
-            this.txtBufferLayer.Location = new System.Drawing.Point(12, 43);
-            this.txtBufferLayer.Name = "txtBufferLayer";
-            this.txtBufferLayer.Size = new System.Drawing.Size(203, 20);
-            this.txtBufferLayer.TabIndex = 1;
-            // 
-            // label9
-            // 
-            this.label9.AutoSize = true;
-            this.label9.Location = new System.Drawing.Point(9, 26);
-            this.label9.Name = "label9";
-            this.label9.Size = new System.Drawing.Size(98, 13);
-            this.label9.TabIndex = 0;
-            this.label9.Text = "Buffer Layer Name:";
-            // 
-            // MgBufferControl
-            // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.Controls.Add(this.groupBox4);
-            this.Controls.Add(this.btnCreate);
-            this.Controls.Add(this.groupBox3);
-            this.Controls.Add(this.groupBox2);
-            this.Controls.Add(this.groupBox1);
-            this.Name = "MgBufferControl";
-            this.Size = new System.Drawing.Size(232, 601);
-            this.groupBox1.ResumeLayout(false);
-            this.groupBox1.PerformLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.numBufferDistance)).EndInit();
-            this.groupBox2.ResumeLayout(false);
-            this.groupBox2.PerformLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.numFillTransparency)).EndInit();
-            this.groupBox3.ResumeLayout(false);
-            this.groupBox3.PerformLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.numLineThickness)).EndInit();
-            this.groupBox4.ResumeLayout(false);
-            this.groupBox4.PerformLayout();
-            this.ResumeLayout(false);
-
-        }
-
-        #endregion
-
-        private System.Windows.Forms.GroupBox groupBox1;
-        private System.Windows.Forms.Label lblSelectFeatures;
-        private System.Windows.Forms.ListBox lstLayers;
-        private System.Windows.Forms.Label label2;
-        private System.Windows.Forms.ComboBox cmbUnits;
-        private System.Windows.Forms.NumericUpDown numBufferDistance;
-        private System.Windows.Forms.Label label1;
-        private System.Windows.Forms.GroupBox groupBox2;
-        private System.Windows.Forms.NumericUpDown numFillTransparency;
-        private System.Windows.Forms.Label label5;
-        private System.Windows.Forms.Button btnFillColor;
-        private System.Windows.Forms.Panel pnlFillColor;
-        private System.Windows.Forms.Label label4;
-        private System.Windows.Forms.ComboBox cmbFillPattern;
-        private System.Windows.Forms.Label label3;
-        private System.Windows.Forms.GroupBox groupBox3;
-        private System.Windows.Forms.NumericUpDown numLineThickness;
-        private System.Windows.Forms.ComboBox cmbBorderPattern;
-        private System.Windows.Forms.Label label6;
-        private System.Windows.Forms.Label label8;
-        private System.Windows.Forms.Button btnBorderColor;
-        private System.Windows.Forms.Label label7;
-        private System.Windows.Forms.Panel pnlBorderColor;
-        private System.Windows.Forms.Button btnCreate;
-        private System.Windows.Forms.GroupBox groupBox4;
-        private System.Windows.Forms.CheckBox chkMergeBuffers;
-        private System.Windows.Forms.TextBox txtBufferLayer;
-        private System.Windows.Forms.Label label9;
-        private System.Windows.Forms.ColorDialog colorPicker;
-        private System.Windows.Forms.Button btnFillBackColor;
-        private System.Windows.Forms.Panel pnlFillBackColor;
-        private System.Windows.Forms.Label label10;
-    }
-}

Modified: trunk/MgDev/Desktop/MapViewer/MgBufferControl.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgBufferControl.cs	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/MgBufferControl.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -1,491 +1,35 @@
 using System;
 using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.Data;
 using System.Text;
-using System.Windows.Forms;
-using System.Globalization;
+using System.ComponentModel;
 
 namespace OSGeo.MapGuide.Viewer
 {
-    public partial class MgBufferControl : UserControl
+    /// <summary>
+    /// A generic component that generates buffers from selected features on the map
+    /// </summary>
+    [ToolboxItem(true)]
+    public class MgBufferControl : MgViewerComponent
     {
-        private IMapViewer _viewer;
-        private MgResourceService _resSvc;
-        private MgFeatureService _featSvc;
-        private string _sessionId;
-
-        public MgBufferControl(IMapViewer viewer)
+        public MgBufferControl()
         {
-            InitializeComponent();
-            _viewer = viewer;
-            _sessionId = Guid.NewGuid().ToString();
-            var provider = viewer.GetProvider();
-            _resSvc = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
-            _featSvc = (MgFeatureService)provider.CreateService(MgServiceType.FeatureService);
-
-            cmbUnits.DataSource = Enum.GetValues(typeof(MeasurementUnit));
-            cmbUnits.SelectedItem = MeasurementUnit.Kilometers;
-            cmbBorderPattern.DataSource = Enum.GetValues(typeof(StockPattern));
-            cmbFillPattern.DataSource = Enum.GetValues(typeof(StockPattern));
-
-            cmbBorderPattern.SelectedItem = StockPattern.Solid;
-            cmbFillPattern.SelectedItem = StockPattern.Solid;
-
-            pnlFillColor.BackColor = Color.Red;
-            pnlBorderColor.BackColor = Color.Black;
-
-            numBufferDistance.Value = 1;
-            numFillTransparency.Value = 50;
-            numLineThickness.Value = 1;
-
-            _viewer.SelectionChanged += new EventHandler(OnViewerSelectedChanged);
+            this.Icon = Properties.Resources.buffer;
+            this.Label = Properties.Resources.TitleBuffer;
         }
 
-        void OnViewerSelectedChanged(object sender, EventArgs e)
+        protected override MgControlImpl CreateControlImpl()
         {
-            lstLayers.Items.Clear();
-            var sel = _viewer.GetSelection();
-            var layers = sel.GetLayers();
-            if (layers != null)
-            {
-                for (var i = 0; i < layers.GetCount(); i++)
-                {
-                    var layer = layers.GetItem(i);
-                    var name = layer.GetName();
-
-                    lstLayers.Items.Add(name);
-                }
-            }
-
-            lblSelectFeatures.Visible = (lstLayers.Items.Count == 0);
+            return new MgBufferControlImpl(this.Viewer);
         }
 
-        private void btnFillColor_Click(object sender, EventArgs e)
+        protected override void SubscribeViewerEvents(IMapViewer viewer)
         {
-            if (colorPicker.ShowDialog() == DialogResult.OK)
-            {
-                pnlFillColor.BackColor = colorPicker.Color;
-            }
+            base.SubscribeViewerEvents(viewer);
         }
 
-        private void btnBorderColor_Click(object sender, EventArgs e)
+        protected override void UnsubscribeViewerEvents(IMapViewer viewer)
         {
-            if (colorPicker.ShowDialog() == DialogResult.OK)
-            {
-                pnlBorderColor.BackColor = colorPicker.Color;
-            }
+            base.UnsubscribeViewerEvents(viewer);
         }
-
-        private void btnFillBackColor_Click(object sender, EventArgs e)
-        {
-            if (colorPicker.ShowDialog() == DialogResult.OK)
-            {
-                pnlFillBackColor.BackColor = colorPicker.Color;
-            }
-        }
-
-        private void btnCreate_Click(object sender, EventArgs e)
-        {
-            var layerName = txtBufferLayer.Text.Trim();
-            if (string.IsNullOrEmpty(layerName))
-            {
-                MessageBox.Show("Please enter a name for this layer");
-                return;
-            }
-
-            if (lstLayers.SelectedItems.Count == 0)
-            {
-                MessageBox.Show("Please include one or more layers to create a buffer from");
-                return;
-            }
-
-            var map = _viewer.GetMap();
-            var layers = map.GetLayers();
-            var provider = _viewer.GetProvider();
-
-            //From here, it's the same logic as buffer.aspx in .net MapGuide AJAX viewer
-            MgResourceIdentifier fsId = new MgResourceIdentifier("Session:" + _sessionId + "//" + txtBufferLayer.Text + "_Buffer.FeatureSource");
-            MgResourceIdentifier ldfId = new MgResourceIdentifier("Session:" + _sessionId + "//" + txtBufferLayer.Text + "_Buffer.LayerDefinition");
-
-            MgLayerBase layer = FindLayer(layers, txtBufferLayer.Text);
-            string[] layerNames = GetLayerNames();
-
-            double distance = Convert.ToDouble(numBufferDistance.Value);
-            MeasurementUnit bUnits = (MeasurementUnit)cmbUnits.SelectedItem;
-            switch (bUnits)
-            {
-                case MeasurementUnit.Feet:
-                    distance *= 0.30480;
-                    break;
-                case MeasurementUnit.Kilometers:
-                    distance *= 1000;
-                    break;
-                case MeasurementUnit.Miles:
-                    distance *= 1609.35;
-                    break;
-            }
-
-            String srsDefMap = GetMapSrs(map);
-            MgCoordinateSystem srsMap = provider.GetMapCoordinateSystem();
-            string mapSrsUnits = "";
-            bool arbitraryMapSrs = (srsMap.GetType() == MgCoordinateSystemType.Arbitrary);
-            if (arbitraryMapSrs)
-                mapSrsUnits = srsMap.GetUnits();
-
-            String xtrans = String.Format("{0:x2}", ((int)(255 * Convert.ToInt32(numFillTransparency.Value) / 100)));
-            var lineColor = ToHtmlColor(pnlBorderColor.BackColor);
-            var foreColor = ToHtmlColor(pnlFillColor.BackColor);
-            var backColor = ToHtmlColor(pnlFillBackColor.BackColor);
-            String layerTempl = string.Format(Properties.Resources.AreaLayerDef,
-                    fsId.ToString(),
-                    "BufferSchema:Buffer",
-                    "GEOM",
-                    cmbFillPattern.SelectedItem,
-                    xtrans + foreColor,
-                    ((0 != 1/*transparent*/) ? "ff" : "00") + backColor,
-                    cmbBorderPattern.SelectedItem,
-                    numLineThickness.Value.ToString(NumberFormatInfo.InvariantInfo),
-                    lineColor
-            );
-            byte[] bytes = Encoding.UTF8.GetBytes(layerTempl);
-            MgByteSource src = new MgByteSource(bytes, bytes.Length);
-            MgByteReader layerDefContent = src.GetReader();
-            _resSvc.SetResource(ldfId, layerDefContent, null);
-
-            bool newBuffer = false;
-            if (layer == null)
-            {
-                newBuffer = true;
-
-                //Targetting a new layer. create a data source for it
-                //
-                MgClassDefinition classDef = new MgClassDefinition();
-
-                classDef.SetName("Buffer");
-                classDef.SetDescription("Feature class for buffer layer");
-                classDef.SetDefaultGeometryPropertyName("GEOM");
-
-                //Set KEY property
-                MgDataPropertyDefinition prop = new MgDataPropertyDefinition("KEY");
-                prop.SetDataType(MgPropertyType.Int32);
-                prop.SetAutoGeneration(true);
-                prop.SetReadOnly(true);
-                classDef.GetIdentityProperties().Add(prop);
-                classDef.GetProperties().Add(prop);
-
-                //Set ID property. Hold this segment ID
-                prop = new MgDataPropertyDefinition("ID");
-                prop.SetDataType(MgPropertyType.Int32);
-                classDef.GetProperties().Add(prop);
-
-                //Set geometry property
-                MgGeometricPropertyDefinition geomProp = new MgGeometricPropertyDefinition("GEOM");
-                //prop.SetGeometryTypes(MgFeatureGeometricType.mfgtSurface); //TODO use the constant when exposed
-                geomProp.SetGeometryTypes(4);
-                classDef.GetProperties().Add(geomProp);
-
-                //Create the schema
-                MgFeatureSchema schema = new MgFeatureSchema("BufferSchema", "Temporary buffer schema");
-                schema.GetClasses().Add(classDef);
-
-                //finally, creation of the feature source
-                MgCreateSdfParams sdfParams = new MgCreateSdfParams("LatLong", map.GetMapSRS(), schema);
-                _featSvc.CreateFeatureSource(fsId, sdfParams);
-
-                //Add layer to map
-                layer = provider.CreateLayer(ldfId);
-                layer.SetName(txtBufferLayer.Text);
-                layer.SetLegendLabel(txtBufferLayer.Text);
-                layer.SetDisplayInLegend(true);
-                layer.SetSelectable(true);
-                layers.Insert(0, layer);
-            }
-            else
-            {
-                //data source already exist. clear its content
-                //
-                ClearDataSource(_featSvc, fsId, "BufferSchema:Buffer");
-            }
-
-            var sel = _viewer.GetSelection();
-            var selLayers = sel.GetLayers();
-
-            MgAgfReaderWriter agfRW = new MgAgfReaderWriter();
-            MgGeometryCollection bufferGeometries = new MgGeometryCollection();
-            MgGeometry geomBuffer;
-
-            MgFeatureCommandCollection commands = new MgFeatureCommandCollection();
-            int featId = 0;
-
-            MgBatchPropertyCollection propCollection = new MgBatchPropertyCollection();
-
-            int excludedLayers = 0;
-            MgCoordinateSystem srsDs = null;
-            MgGeometryCollection inputGeometries = new MgGeometryCollection();
-
-            int bufferFeatures = 0;
-            for (int li = 0; li < selLayers.GetCount(); li++)
-            {
-                MgLayerBase selLayer = selLayers.GetItem(li);
-                bool inputLayer = false;
-                String selLayerName = selLayer.GetName();
-                for (int il = 0; il < layerNames.Length; il++)
-                {
-                    if (layerNames[il].Equals(selLayerName))
-                    {
-                        inputLayer = true;
-                        break;
-                    }
-                }
-                if (inputLayer == false)
-                {
-                    continue;
-                }
-
-                // get the data source SRS
-                //
-                MgResourceIdentifier featSourceId = new MgResourceIdentifier(selLayer.GetFeatureSourceId());
-                MgSpatialContextReader ctxs = _featSvc.GetSpatialContexts(featSourceId, false);
-                String srsDefDs = "";
-                if (ctxs != null && ctxs.ReadNext())
-                    srsDefDs = ctxs.GetCoordinateSystemWkt();
-
-                if (srsDefDs == null || srsDefDs.Length == 0)
-                {
-                    excludedLayers++;
-                    continue;
-                }
-
-                var srsFactory = new MgCoordinateSystemFactory();
-                srsDs = srsFactory.Create(srsDefDs);
-                bool arbitraryDsSrs = (srsDs.GetType() == MgCoordinateSystemType.Arbitrary);
-                String dsSrsUnits = "";
-
-                if (arbitraryDsSrs)
-                    dsSrsUnits = srsDs.GetUnits();
-
-                // exclude layer if:
-                //  the map is non-arbitrary and the layer is arbitrary or vice-versa
-                //     or
-                //  layer and map are both arbitrary but have different units
-                //
-                if ((arbitraryDsSrs != arbitraryMapSrs) || (arbitraryDsSrs && (dsSrsUnits != mapSrsUnits)))
-                {
-                    excludedLayers++;
-                    continue;
-                }
-
-                // calculate distance in the data source SRS units
-                //
-                double dist = srsDs.ConvertMetersToCoordinateSystemUnits(distance);
-
-                // calculate great circle unless data source srs is arbitrary
-                MgCoordinateSystemMeasure measure;
-                if (!arbitraryDsSrs)
-                    measure = srsDs.GetMeasure();
-                else
-                    measure = null;
-
-                // create a SRS transformer if necessary
-                MgCoordinateSystemTransform srsXform;
-                if (!srsDefDs.Equals(srsDefMap))
-                    srsXform = srsFactory.GetTransform(srsDs, srsMap);
-                else
-                    srsXform = null;
-
-                String featureClassName = selLayer.GetFeatureClassName();
-                String filter = sel.GenerateFilter(selLayer, featureClassName);
-                if (filter == null || filter.Length == 0)
-                    continue;
-
-                MgFeatureQueryOptions query = new MgFeatureQueryOptions();
-                query.SetFilter(filter);
-
-                MgResourceIdentifier featureSource = new MgResourceIdentifier(selLayer.GetFeatureSourceId());
-
-                MgFeatureReader features = _featSvc.SelectFeatures(featureSource, featureClassName, query);
-
-                if (features.ReadNext())
-                {
-                    MgClassDefinition classDef = features.GetClassDefinition();
-                    String geomPropName = classDef.GetDefaultGeometryPropertyName();
-
-                    do
-                    {
-                        MgByteReader geomReader = features.GetGeometry(geomPropName);
-                        MgGeometry geom = agfRW.Read(geomReader);
-
-                        if (!chkMergeBuffers.Checked)
-                        {
-                            geomBuffer = geom.Buffer(dist, measure);
-                            if (geomBuffer != null)
-                            {
-                                if (srsXform != null)
-                                    geomBuffer = (MgGeometry)geomBuffer.Transform(srsXform);
-                                AddFeatureToCollection(propCollection, agfRW, featId++, geomBuffer);
-                                bufferFeatures++;
-                            }
-                        }
-                        else
-                        {
-                            if (srsXform != null)
-                                geom = (MgGeometry)geom.Transform(srsXform);
-                            inputGeometries.Add(geom);
-                        }
-                    }
-                    while (features.ReadNext());
-
-                    features.Close();
-                }
-            }
-
-            if (chkMergeBuffers.Checked)
-            {
-                if (inputGeometries.GetCount() > 0)
-                {
-                    double dist = srsMap.ConvertMetersToCoordinateSystemUnits(distance);
-                    MgCoordinateSystemMeasure measure;
-                    if (!arbitraryMapSrs)
-                        measure = srsMap.GetMeasure();
-                    else
-                        measure = null;
-
-                    MgGeometryFactory geomFactory = new MgGeometryFactory();
-                    geomBuffer = geomFactory.CreateMultiGeometry(inputGeometries).Buffer(dist, measure);
-                    if (geomBuffer != null)
-                    {
-                        AddFeatureToCollection(propCollection, agfRW, featId, geomBuffer);
-                        bufferFeatures = 1;
-                    }
-                }
-            }
-
-            if (propCollection.GetCount() > 0)
-            {
-                commands.Add(new MgInsertFeatures("BufferSchema:Buffer", propCollection));
-
-                //Insert the features in the temporary data source
-                //
-                ReleaseReader(_featSvc.UpdateFeatures(fsId, commands, false), commands);
-            }
-
-            // Save the new map state
-            //
-            layer.ForceRefresh();
-            _viewer.RefreshMap();
-
-            //build report message
-            MessageBox.Show("Buffer layer (" + txtBufferLayer.Text + ") " + (newBuffer ? "created" : "updated"));
-        }
-
-        private string[] GetLayerNames()
-        {
-            var items = new List<string>();
-            foreach (var it in lstLayers.Items)
-            {
-                items.Add(it.ToString());
-            }
-            return items.ToArray();
-        }
-
-        static string ToHtmlColor(Color color)
-        {
-            return String.Format("{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
-        }
-
-        static MgLayerBase FindLayer(MgLayerCollection layers, String layerName)
-        {
-            MgLayerBase layer = null;
-            int i = 0;
-            for (i = 0; i < layers.GetCount(); i++)
-            {
-                MgLayerBase layer1 = layers.GetItem(i);
-
-                if (layer1.GetName() == layerName)
-                {
-                    layer = layer1;
-                    break;
-                }
-            }
-            return layer;
-        }
-
-        static string GetMapSrs(MgMapBase map)
-        {
-            try
-            {
-                String srs = map.GetMapSRS();
-                if (srs != "")
-                    return srs;
-            }
-            catch (MgException e)
-            {
-            }
-
-            //No SRS, set to ArbitrayXY meters
-            //
-            return "LOCALCS[\"Non-Earth (Meter)\",LOCAL_DATUM[\"Local Datum\",0],UNIT[\"Meter\", 1],AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]]";
-        }
-
-        static void ClearDataSource(MgFeatureService featSvc, MgResourceIdentifier fsId, String featureName)
-        {
-            MgDeleteFeatures deleteCmd = new MgDeleteFeatures(featureName, "ID >= 0");
-            MgFeatureCommandCollection commands = new MgFeatureCommandCollection();
-            commands.Add(deleteCmd);
-            featSvc.UpdateFeatures(fsId, commands, false);
-        }
-
-        static void ReleaseReader(MgPropertyCollection res, MgFeatureCommandCollection commands)
-        {
-            if (res == null)
-                return;
-
-            for (int i = 0; i < res.GetCount(); i++)
-            {
-                MgFeatureCommand cmd = commands.GetItem(i);
-                if (cmd is MgInsertFeatures)
-                {
-                    MgFeatureProperty resProp = res.GetItem(i) as MgFeatureProperty;
-                    if (resProp != null)
-                    {
-                        MgFeatureReader reader = resProp.GetValue() as MgFeatureReader;
-                        if (reader == null)
-                            return;
-                        reader.Close();
-                    }
-                }
-            }
-        }
-
-        static void AddFeatureToCollection(MgBatchPropertyCollection propCollection, MgAgfReaderWriter agfRW, int featureId, MgGeometry featureGeom)
-        {
-            MgPropertyCollection bufferProps = new MgPropertyCollection();
-            MgInt32Property idProp = new MgInt32Property("ID", featureId);
-            bufferProps.Add(idProp);
-            MgByteReader geomReader = agfRW.Write(featureGeom);
-            MgGeometryProperty geomProp = new MgGeometryProperty("GEOM", geomReader);
-            bufferProps.Add(geomProp);
-            propCollection.Add(bufferProps);
-        }
     }
-
-    public enum StockPattern
-    {
-        Solid,
-        Net,
-        Line,
-        Line_45,
-        Line_90,
-        Line_135,
-        Square,
-        Box,
-        Cross,
-        Dash,
-        Dolmit,
-        Hex,
-        Sacncr,
-        Steel
-    }
 }

Deleted: trunk/MgDev/Desktop/MapViewer/MgBufferControl.resx
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgBufferControl.resx	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/MgBufferControl.resx	2012-05-03 14:38:06 UTC (rev 6609)
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <metadata name="colorPicker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>17, 17</value>
-  </metadata>
-</root>

Copied: trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.Designer.cs (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgBufferControlImpl.Designer.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.Designer.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.Designer.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,457 @@
+namespace OSGeo.MapGuide.Viewer
+{
+    partial class MgBufferControlImpl
+    {
+        /// <summary> 
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.groupBox1 = new System.Windows.Forms.GroupBox();
+            this.lstLayers = new System.Windows.Forms.ListBox();
+            this.label2 = new System.Windows.Forms.Label();
+            this.cmbUnits = new System.Windows.Forms.ComboBox();
+            this.numBufferDistance = new System.Windows.Forms.NumericUpDown();
+            this.label1 = new System.Windows.Forms.Label();
+            this.lblSelectFeatures = new System.Windows.Forms.Label();
+            this.groupBox2 = new System.Windows.Forms.GroupBox();
+            this.btnFillBackColor = new System.Windows.Forms.Button();
+            this.pnlFillBackColor = new System.Windows.Forms.Panel();
+            this.label10 = new System.Windows.Forms.Label();
+            this.numFillTransparency = new System.Windows.Forms.NumericUpDown();
+            this.label5 = new System.Windows.Forms.Label();
+            this.btnFillColor = new System.Windows.Forms.Button();
+            this.pnlFillColor = new System.Windows.Forms.Panel();
+            this.label4 = new System.Windows.Forms.Label();
+            this.cmbFillPattern = new System.Windows.Forms.ComboBox();
+            this.label3 = new System.Windows.Forms.Label();
+            this.groupBox3 = new System.Windows.Forms.GroupBox();
+            this.numLineThickness = new System.Windows.Forms.NumericUpDown();
+            this.cmbBorderPattern = new System.Windows.Forms.ComboBox();
+            this.label6 = new System.Windows.Forms.Label();
+            this.label8 = new System.Windows.Forms.Label();
+            this.btnBorderColor = new System.Windows.Forms.Button();
+            this.label7 = new System.Windows.Forms.Label();
+            this.pnlBorderColor = new System.Windows.Forms.Panel();
+            this.btnCreate = new System.Windows.Forms.Button();
+            this.groupBox4 = new System.Windows.Forms.GroupBox();
+            this.chkMergeBuffers = new System.Windows.Forms.CheckBox();
+            this.txtBufferLayer = new System.Windows.Forms.TextBox();
+            this.label9 = new System.Windows.Forms.Label();
+            this.colorPicker = new System.Windows.Forms.ColorDialog();
+            this.groupBox1.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numBufferDistance)).BeginInit();
+            this.groupBox2.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numFillTransparency)).BeginInit();
+            this.groupBox3.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numLineThickness)).BeginInit();
+            this.groupBox4.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // groupBox1
+            // 
+            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.groupBox1.Controls.Add(this.lstLayers);
+            this.groupBox1.Controls.Add(this.label2);
+            this.groupBox1.Controls.Add(this.cmbUnits);
+            this.groupBox1.Controls.Add(this.numBufferDistance);
+            this.groupBox1.Controls.Add(this.label1);
+            this.groupBox1.Controls.Add(this.lblSelectFeatures);
+            this.groupBox1.Location = new System.Drawing.Point(0, 0);
+            this.groupBox1.Name = "groupBox1";
+            this.groupBox1.Size = new System.Drawing.Size(232, 220);
+            this.groupBox1.TabIndex = 0;
+            this.groupBox1.TabStop = false;
+            this.groupBox1.Text = "Buffer Settings";
+            // 
+            // lstLayers
+            // 
+            this.lstLayers.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.lstLayers.FormattingEnabled = true;
+            this.lstLayers.Location = new System.Drawing.Point(9, 126);
+            this.lstLayers.Name = "lstLayers";
+            this.lstLayers.Size = new System.Drawing.Size(206, 82);
+            this.lstLayers.TabIndex = 5;
+            // 
+            // label2
+            // 
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(6, 101);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(180, 13);
+            this.label2.TabIndex = 4;
+            this.label2.Text = "Includes the following layers in buffer";
+            // 
+            // cmbUnits
+            // 
+            this.cmbUnits.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbUnits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbUnits.FormattingEnabled = true;
+            this.cmbUnits.Location = new System.Drawing.Point(105, 66);
+            this.cmbUnits.Name = "cmbUnits";
+            this.cmbUnits.Size = new System.Drawing.Size(110, 21);
+            this.cmbUnits.TabIndex = 3;
+            // 
+            // numBufferDistance
+            // 
+            this.numBufferDistance.Location = new System.Drawing.Point(9, 67);
+            this.numBufferDistance.Maximum = new decimal(new int[] {
+            100000,
+            0,
+            0,
+            0});
+            this.numBufferDistance.Minimum = new decimal(new int[] {
+            100000,
+            0,
+            0,
+            -2147483648});
+            this.numBufferDistance.Name = "numBufferDistance";
+            this.numBufferDistance.Size = new System.Drawing.Size(92, 20);
+            this.numBufferDistance.TabIndex = 2;
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(6, 50);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(126, 13);
+            this.label1.TabIndex = 1;
+            this.label1.Text = "Distance around features";
+            // 
+            // lblSelectFeatures
+            // 
+            this.lblSelectFeatures.BackColor = System.Drawing.Color.White;
+            this.lblSelectFeatures.ForeColor = System.Drawing.Color.Blue;
+            this.lblSelectFeatures.Location = new System.Drawing.Point(6, 16);
+            this.lblSelectFeatures.Name = "lblSelectFeatures";
+            this.lblSelectFeatures.Size = new System.Drawing.Size(209, 23);
+            this.lblSelectFeatures.TabIndex = 0;
+            this.lblSelectFeatures.Text = "Select Features on the Map first";
+            this.lblSelectFeatures.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // groupBox2
+            // 
+            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.groupBox2.Controls.Add(this.btnFillBackColor);
+            this.groupBox2.Controls.Add(this.pnlFillBackColor);
+            this.groupBox2.Controls.Add(this.label10);
+            this.groupBox2.Controls.Add(this.numFillTransparency);
+            this.groupBox2.Controls.Add(this.label5);
+            this.groupBox2.Controls.Add(this.btnFillColor);
+            this.groupBox2.Controls.Add(this.pnlFillColor);
+            this.groupBox2.Controls.Add(this.label4);
+            this.groupBox2.Controls.Add(this.cmbFillPattern);
+            this.groupBox2.Controls.Add(this.label3);
+            this.groupBox2.Location = new System.Drawing.Point(0, 220);
+            this.groupBox2.Name = "groupBox2";
+            this.groupBox2.Size = new System.Drawing.Size(232, 144);
+            this.groupBox2.TabIndex = 1;
+            this.groupBox2.TabStop = false;
+            this.groupBox2.Text = "Fill Style";
+            // 
+            // btnFillBackColor
+            // 
+            this.btnFillBackColor.Location = new System.Drawing.Point(183, 102);
+            this.btnFillBackColor.Name = "btnFillBackColor";
+            this.btnFillBackColor.Size = new System.Drawing.Size(32, 23);
+            this.btnFillBackColor.TabIndex = 9;
+            this.btnFillBackColor.Text = "...";
+            this.btnFillBackColor.UseVisualStyleBackColor = true;
+            this.btnFillBackColor.Click += new System.EventHandler(this.btnFillBackColor_Click);
+            // 
+            // pnlFillBackColor
+            // 
+            this.pnlFillBackColor.Location = new System.Drawing.Point(95, 103);
+            this.pnlFillBackColor.Name = "pnlFillBackColor";
+            this.pnlFillBackColor.Size = new System.Drawing.Size(82, 22);
+            this.pnlFillBackColor.TabIndex = 8;
+            // 
+            // label10
+            // 
+            this.label10.AutoSize = true;
+            this.label10.Location = new System.Drawing.Point(30, 107);
+            this.label10.Name = "label10";
+            this.label10.Size = new System.Drawing.Size(59, 13);
+            this.label10.TabIndex = 7;
+            this.label10.Text = "Back Color";
+            // 
+            // numFillTransparency
+            // 
+            this.numFillTransparency.Location = new System.Drawing.Point(95, 77);
+            this.numFillTransparency.Name = "numFillTransparency";
+            this.numFillTransparency.Size = new System.Drawing.Size(120, 20);
+            this.numFillTransparency.TabIndex = 6;
+            // 
+            // label5
+            // 
+            this.label5.AutoSize = true;
+            this.label5.Location = new System.Drawing.Point(17, 79);
+            this.label5.Name = "label5";
+            this.label5.Size = new System.Drawing.Size(72, 13);
+            this.label5.TabIndex = 5;
+            this.label5.Text = "Transparency";
+            // 
+            // btnFillColor
+            // 
+            this.btnFillColor.Location = new System.Drawing.Point(183, 48);
+            this.btnFillColor.Name = "btnFillColor";
+            this.btnFillColor.Size = new System.Drawing.Size(32, 23);
+            this.btnFillColor.TabIndex = 4;
+            this.btnFillColor.Text = "...";
+            this.btnFillColor.UseVisualStyleBackColor = true;
+            this.btnFillColor.Click += new System.EventHandler(this.btnFillColor_Click);
+            // 
+            // pnlFillColor
+            // 
+            this.pnlFillColor.Location = new System.Drawing.Point(95, 49);
+            this.pnlFillColor.Name = "pnlFillColor";
+            this.pnlFillColor.Size = new System.Drawing.Size(82, 22);
+            this.pnlFillColor.TabIndex = 3;
+            // 
+            // label4
+            // 
+            this.label4.AutoSize = true;
+            this.label4.Location = new System.Drawing.Point(34, 53);
+            this.label4.Name = "label4";
+            this.label4.Size = new System.Drawing.Size(55, 13);
+            this.label4.TabIndex = 2;
+            this.label4.Text = "Fore Color";
+            // 
+            // cmbFillPattern
+            // 
+            this.cmbFillPattern.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbFillPattern.FormattingEnabled = true;
+            this.cmbFillPattern.Location = new System.Drawing.Point(95, 23);
+            this.cmbFillPattern.Name = "cmbFillPattern";
+            this.cmbFillPattern.Size = new System.Drawing.Size(120, 21);
+            this.cmbFillPattern.TabIndex = 1;
+            // 
+            // label3
+            // 
+            this.label3.AutoSize = true;
+            this.label3.Location = new System.Drawing.Point(48, 26);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(41, 13);
+            this.label3.TabIndex = 0;
+            this.label3.Text = "Pattern";
+            // 
+            // groupBox3
+            // 
+            this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.groupBox3.Controls.Add(this.numLineThickness);
+            this.groupBox3.Controls.Add(this.cmbBorderPattern);
+            this.groupBox3.Controls.Add(this.label6);
+            this.groupBox3.Controls.Add(this.label8);
+            this.groupBox3.Controls.Add(this.btnBorderColor);
+            this.groupBox3.Controls.Add(this.label7);
+            this.groupBox3.Controls.Add(this.pnlBorderColor);
+            this.groupBox3.Location = new System.Drawing.Point(0, 364);
+            this.groupBox3.Name = "groupBox3";
+            this.groupBox3.Size = new System.Drawing.Size(232, 100);
+            this.groupBox3.TabIndex = 2;
+            this.groupBox3.TabStop = false;
+            this.groupBox3.Text = "Border Style";
+            // 
+            // numLineThickness
+            // 
+            this.numLineThickness.Location = new System.Drawing.Point(95, 73);
+            this.numLineThickness.Name = "numLineThickness";
+            this.numLineThickness.Size = new System.Drawing.Size(120, 20);
+            this.numLineThickness.TabIndex = 13;
+            // 
+            // cmbBorderPattern
+            // 
+            this.cmbBorderPattern.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbBorderPattern.FormattingEnabled = true;
+            this.cmbBorderPattern.Location = new System.Drawing.Point(95, 19);
+            this.cmbBorderPattern.Name = "cmbBorderPattern";
+            this.cmbBorderPattern.Size = new System.Drawing.Size(120, 21);
+            this.cmbBorderPattern.TabIndex = 8;
+            // 
+            // label6
+            // 
+            this.label6.AutoSize = true;
+            this.label6.Location = new System.Drawing.Point(17, 75);
+            this.label6.Name = "label6";
+            this.label6.Size = new System.Drawing.Size(72, 13);
+            this.label6.TabIndex = 12;
+            this.label6.Text = "Transparency";
+            // 
+            // label8
+            // 
+            this.label8.AutoSize = true;
+            this.label8.Location = new System.Drawing.Point(48, 22);
+            this.label8.Name = "label8";
+            this.label8.Size = new System.Drawing.Size(41, 13);
+            this.label8.TabIndex = 7;
+            this.label8.Text = "Pattern";
+            // 
+            // btnBorderColor
+            // 
+            this.btnBorderColor.Location = new System.Drawing.Point(183, 44);
+            this.btnBorderColor.Name = "btnBorderColor";
+            this.btnBorderColor.Size = new System.Drawing.Size(32, 23);
+            this.btnBorderColor.TabIndex = 11;
+            this.btnBorderColor.Text = "...";
+            this.btnBorderColor.UseVisualStyleBackColor = true;
+            this.btnBorderColor.Click += new System.EventHandler(this.btnBorderColor_Click);
+            // 
+            // label7
+            // 
+            this.label7.AutoSize = true;
+            this.label7.Location = new System.Drawing.Point(58, 49);
+            this.label7.Name = "label7";
+            this.label7.Size = new System.Drawing.Size(31, 13);
+            this.label7.TabIndex = 9;
+            this.label7.Text = "Color";
+            // 
+            // pnlBorderColor
+            // 
+            this.pnlBorderColor.Location = new System.Drawing.Point(95, 45);
+            this.pnlBorderColor.Name = "pnlBorderColor";
+            this.pnlBorderColor.Size = new System.Drawing.Size(82, 22);
+            this.pnlBorderColor.TabIndex = 10;
+            // 
+            // btnCreate
+            // 
+            this.btnCreate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.btnCreate.Location = new System.Drawing.Point(9, 567);
+            this.btnCreate.Name = "btnCreate";
+            this.btnCreate.Size = new System.Drawing.Size(98, 23);
+            this.btnCreate.TabIndex = 3;
+            this.btnCreate.Text = "Create Buffer";
+            this.btnCreate.UseVisualStyleBackColor = true;
+            this.btnCreate.Click += new System.EventHandler(this.btnCreate_Click);
+            // 
+            // groupBox4
+            // 
+            this.groupBox4.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.groupBox4.Controls.Add(this.chkMergeBuffers);
+            this.groupBox4.Controls.Add(this.txtBufferLayer);
+            this.groupBox4.Controls.Add(this.label9);
+            this.groupBox4.Location = new System.Drawing.Point(0, 464);
+            this.groupBox4.Name = "groupBox4";
+            this.groupBox4.Size = new System.Drawing.Size(232, 97);
+            this.groupBox4.TabIndex = 4;
+            this.groupBox4.TabStop = false;
+            this.groupBox4.Text = "Other";
+            // 
+            // chkMergeBuffers
+            // 
+            this.chkMergeBuffers.AutoSize = true;
+            this.chkMergeBuffers.Checked = true;
+            this.chkMergeBuffers.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.chkMergeBuffers.Location = new System.Drawing.Point(12, 69);
+            this.chkMergeBuffers.Name = "chkMergeBuffers";
+            this.chkMergeBuffers.Size = new System.Drawing.Size(117, 17);
+            this.chkMergeBuffers.TabIndex = 2;
+            this.chkMergeBuffers.Text = "Merge Buffer Areas";
+            this.chkMergeBuffers.UseVisualStyleBackColor = true;
+            // 
+            // txtBufferLayer
+            // 
+            this.txtBufferLayer.Location = new System.Drawing.Point(12, 43);
+            this.txtBufferLayer.Name = "txtBufferLayer";
+            this.txtBufferLayer.Size = new System.Drawing.Size(203, 20);
+            this.txtBufferLayer.TabIndex = 1;
+            // 
+            // label9
+            // 
+            this.label9.AutoSize = true;
+            this.label9.Location = new System.Drawing.Point(9, 26);
+            this.label9.Name = "label9";
+            this.label9.Size = new System.Drawing.Size(98, 13);
+            this.label9.TabIndex = 0;
+            this.label9.Text = "Buffer Layer Name:";
+            // 
+            // MgBufferControl
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.groupBox4);
+            this.Controls.Add(this.btnCreate);
+            this.Controls.Add(this.groupBox3);
+            this.Controls.Add(this.groupBox2);
+            this.Controls.Add(this.groupBox1);
+            this.Name = "MgBufferControl";
+            this.Size = new System.Drawing.Size(232, 601);
+            this.groupBox1.ResumeLayout(false);
+            this.groupBox1.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numBufferDistance)).EndInit();
+            this.groupBox2.ResumeLayout(false);
+            this.groupBox2.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numFillTransparency)).EndInit();
+            this.groupBox3.ResumeLayout(false);
+            this.groupBox3.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numLineThickness)).EndInit();
+            this.groupBox4.ResumeLayout(false);
+            this.groupBox4.PerformLayout();
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.GroupBox groupBox1;
+        private System.Windows.Forms.Label lblSelectFeatures;
+        private System.Windows.Forms.ListBox lstLayers;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.ComboBox cmbUnits;
+        private System.Windows.Forms.NumericUpDown numBufferDistance;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.GroupBox groupBox2;
+        private System.Windows.Forms.NumericUpDown numFillTransparency;
+        private System.Windows.Forms.Label label5;
+        private System.Windows.Forms.Button btnFillColor;
+        private System.Windows.Forms.Panel pnlFillColor;
+        private System.Windows.Forms.Label label4;
+        private System.Windows.Forms.ComboBox cmbFillPattern;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.GroupBox groupBox3;
+        private System.Windows.Forms.NumericUpDown numLineThickness;
+        private System.Windows.Forms.ComboBox cmbBorderPattern;
+        private System.Windows.Forms.Label label6;
+        private System.Windows.Forms.Label label8;
+        private System.Windows.Forms.Button btnBorderColor;
+        private System.Windows.Forms.Label label7;
+        private System.Windows.Forms.Panel pnlBorderColor;
+        private System.Windows.Forms.Button btnCreate;
+        private System.Windows.Forms.GroupBox groupBox4;
+        private System.Windows.Forms.CheckBox chkMergeBuffers;
+        private System.Windows.Forms.TextBox txtBufferLayer;
+        private System.Windows.Forms.Label label9;
+        private System.Windows.Forms.ColorDialog colorPicker;
+        private System.Windows.Forms.Button btnFillBackColor;
+        private System.Windows.Forms.Panel pnlFillBackColor;
+        private System.Windows.Forms.Label label10;
+    }
+}

Copied: trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,493 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using System.Globalization;
+
+namespace OSGeo.MapGuide.Viewer
+{
+    internal partial class MgBufferControlImpl : MgControlImpl
+    {
+        private IMapViewer _viewer;
+        private MgResourceService _resSvc;
+        private MgFeatureService _featSvc;
+        private string _sessionId;
+
+        public MgBufferControlImpl(IMapViewer viewer)
+        {
+            InitializeComponent();
+            this.Title = Properties.Resources.TitleBuffer;
+            _viewer = viewer;
+            _sessionId = Guid.NewGuid().ToString();
+            var provider = viewer.GetProvider();
+            _resSvc = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
+            _featSvc = (MgFeatureService)provider.CreateService(MgServiceType.FeatureService);
+
+            cmbUnits.DataSource = Enum.GetValues(typeof(MeasurementUnit));
+            cmbUnits.SelectedItem = MeasurementUnit.Kilometers;
+            cmbBorderPattern.DataSource = Enum.GetValues(typeof(StockPattern));
+            cmbFillPattern.DataSource = Enum.GetValues(typeof(StockPattern));
+
+            cmbBorderPattern.SelectedItem = StockPattern.Solid;
+            cmbFillPattern.SelectedItem = StockPattern.Solid;
+
+            pnlFillColor.BackColor = Color.Red;
+            pnlBorderColor.BackColor = Color.Black;
+
+            numBufferDistance.Value = 1;
+            numFillTransparency.Value = 50;
+            numLineThickness.Value = 1;
+
+            _viewer.SelectionChanged += new EventHandler(OnViewerSelectedChanged);
+            OnViewerSelectedChanged(this, EventArgs.Empty);
+        }
+
+        void OnViewerSelectedChanged(object sender, EventArgs e)
+        {
+            lstLayers.Items.Clear();
+            var sel = _viewer.GetSelection();
+            var layers = sel.GetLayers();
+            if (layers != null)
+            {
+                for (var i = 0; i < layers.GetCount(); i++)
+                {
+                    var layer = layers.GetItem(i);
+                    var name = layer.GetName();
+
+                    lstLayers.Items.Add(name);
+                }
+            }
+
+            lblSelectFeatures.Visible = (lstLayers.Items.Count == 0);
+        }
+
+        private void btnFillColor_Click(object sender, EventArgs e)
+        {
+            if (colorPicker.ShowDialog() == DialogResult.OK)
+            {
+                pnlFillColor.BackColor = colorPicker.Color;
+            }
+        }
+
+        private void btnBorderColor_Click(object sender, EventArgs e)
+        {
+            if (colorPicker.ShowDialog() == DialogResult.OK)
+            {
+                pnlBorderColor.BackColor = colorPicker.Color;
+            }
+        }
+
+        private void btnFillBackColor_Click(object sender, EventArgs e)
+        {
+            if (colorPicker.ShowDialog() == DialogResult.OK)
+            {
+                pnlFillBackColor.BackColor = colorPicker.Color;
+            }
+        }
+
+        private void btnCreate_Click(object sender, EventArgs e)
+        {
+            var layerName = txtBufferLayer.Text.Trim();
+            if (string.IsNullOrEmpty(layerName))
+            {
+                MessageBox.Show("Please enter a name for this layer");
+                return;
+            }
+
+            if (lstLayers.SelectedItems.Count == 0)
+            {
+                MessageBox.Show("Please include one or more layers to create a buffer from");
+                return;
+            }
+
+            var map = _viewer.GetMap();
+            var layers = map.GetLayers();
+            var provider = _viewer.GetProvider();
+
+            //From here, it's the same logic as buffer.aspx in .net MapGuide AJAX viewer
+            MgResourceIdentifier fsId = new MgResourceIdentifier("Session:" + _sessionId + "//" + txtBufferLayer.Text + "_Buffer.FeatureSource");
+            MgResourceIdentifier ldfId = new MgResourceIdentifier("Session:" + _sessionId + "//" + txtBufferLayer.Text + "_Buffer.LayerDefinition");
+
+            MgLayerBase layer = FindLayer(layers, txtBufferLayer.Text);
+            string[] layerNames = GetLayerNames();
+
+            double distance = Convert.ToDouble(numBufferDistance.Value);
+            MeasurementUnit bUnits = (MeasurementUnit)cmbUnits.SelectedItem;
+            switch (bUnits)
+            {
+                case MeasurementUnit.Feet:
+                    distance *= 0.30480;
+                    break;
+                case MeasurementUnit.Kilometers:
+                    distance *= 1000;
+                    break;
+                case MeasurementUnit.Miles:
+                    distance *= 1609.35;
+                    break;
+            }
+
+            String srsDefMap = GetMapSrs(map);
+            MgCoordinateSystem srsMap = provider.GetMapCoordinateSystem();
+            string mapSrsUnits = "";
+            bool arbitraryMapSrs = (srsMap.GetType() == MgCoordinateSystemType.Arbitrary);
+            if (arbitraryMapSrs)
+                mapSrsUnits = srsMap.GetUnits();
+
+            String xtrans = String.Format("{0:x2}", ((int)(255 * Convert.ToInt32(numFillTransparency.Value) / 100)));
+            var lineColor = ToHtmlColor(pnlBorderColor.BackColor);
+            var foreColor = ToHtmlColor(pnlFillColor.BackColor);
+            var backColor = ToHtmlColor(pnlFillBackColor.BackColor);
+            String layerTempl = string.Format(Properties.Resources.AreaLayerDef,
+                    fsId.ToString(),
+                    "BufferSchema:Buffer",
+                    "GEOM",
+                    cmbFillPattern.SelectedItem,
+                    xtrans + foreColor,
+                    ((0 != 1/*transparent*/) ? "ff" : "00") + backColor,
+                    cmbBorderPattern.SelectedItem,
+                    numLineThickness.Value.ToString(NumberFormatInfo.InvariantInfo),
+                    lineColor
+            );
+            byte[] bytes = Encoding.UTF8.GetBytes(layerTempl);
+            MgByteSource src = new MgByteSource(bytes, bytes.Length);
+            MgByteReader layerDefContent = src.GetReader();
+            _resSvc.SetResource(ldfId, layerDefContent, null);
+
+            bool newBuffer = false;
+            if (layer == null)
+            {
+                newBuffer = true;
+
+                //Targetting a new layer. create a data source for it
+                //
+                MgClassDefinition classDef = new MgClassDefinition();
+
+                classDef.SetName("Buffer");
+                classDef.SetDescription("Feature class for buffer layer");
+                classDef.SetDefaultGeometryPropertyName("GEOM");
+
+                //Set KEY property
+                MgDataPropertyDefinition prop = new MgDataPropertyDefinition("KEY");
+                prop.SetDataType(MgPropertyType.Int32);
+                prop.SetAutoGeneration(true);
+                prop.SetReadOnly(true);
+                classDef.GetIdentityProperties().Add(prop);
+                classDef.GetProperties().Add(prop);
+
+                //Set ID property. Hold this segment ID
+                prop = new MgDataPropertyDefinition("ID");
+                prop.SetDataType(MgPropertyType.Int32);
+                classDef.GetProperties().Add(prop);
+
+                //Set geometry property
+                MgGeometricPropertyDefinition geomProp = new MgGeometricPropertyDefinition("GEOM");
+                //prop.SetGeometryTypes(MgFeatureGeometricType.mfgtSurface); //TODO use the constant when exposed
+                geomProp.SetGeometryTypes(4);
+                classDef.GetProperties().Add(geomProp);
+
+                //Create the schema
+                MgFeatureSchema schema = new MgFeatureSchema("BufferSchema", "Temporary buffer schema");
+                schema.GetClasses().Add(classDef);
+
+                //finally, creation of the feature source
+                MgCreateSdfParams sdfParams = new MgCreateSdfParams("LatLong", map.GetMapSRS(), schema);
+                _featSvc.CreateFeatureSource(fsId, sdfParams);
+
+                //Add layer to map
+                layer = provider.CreateLayer(ldfId);
+                layer.SetName(txtBufferLayer.Text);
+                layer.SetLegendLabel(txtBufferLayer.Text);
+                layer.SetDisplayInLegend(true);
+                layer.SetSelectable(true);
+                layers.Insert(0, layer);
+            }
+            else
+            {
+                //data source already exist. clear its content
+                //
+                ClearDataSource(_featSvc, fsId, "BufferSchema:Buffer");
+            }
+
+            var sel = _viewer.GetSelection();
+            var selLayers = sel.GetLayers();
+
+            MgAgfReaderWriter agfRW = new MgAgfReaderWriter();
+            MgGeometryCollection bufferGeometries = new MgGeometryCollection();
+            MgGeometry geomBuffer;
+
+            MgFeatureCommandCollection commands = new MgFeatureCommandCollection();
+            int featId = 0;
+
+            MgBatchPropertyCollection propCollection = new MgBatchPropertyCollection();
+
+            int excludedLayers = 0;
+            MgCoordinateSystem srsDs = null;
+            MgGeometryCollection inputGeometries = new MgGeometryCollection();
+
+            int bufferFeatures = 0;
+            for (int li = 0; li < selLayers.GetCount(); li++)
+            {
+                MgLayerBase selLayer = selLayers.GetItem(li);
+                bool inputLayer = false;
+                String selLayerName = selLayer.GetName();
+                for (int il = 0; il < layerNames.Length; il++)
+                {
+                    if (layerNames[il].Equals(selLayerName))
+                    {
+                        inputLayer = true;
+                        break;
+                    }
+                }
+                if (inputLayer == false)
+                {
+                    continue;
+                }
+
+                // get the data source SRS
+                //
+                MgResourceIdentifier featSourceId = new MgResourceIdentifier(selLayer.GetFeatureSourceId());
+                MgSpatialContextReader ctxs = _featSvc.GetSpatialContexts(featSourceId, false);
+                String srsDefDs = "";
+                if (ctxs != null && ctxs.ReadNext())
+                    srsDefDs = ctxs.GetCoordinateSystemWkt();
+
+                if (srsDefDs == null || srsDefDs.Length == 0)
+                {
+                    excludedLayers++;
+                    continue;
+                }
+
+                var srsFactory = new MgCoordinateSystemFactory();
+                srsDs = srsFactory.Create(srsDefDs);
+                bool arbitraryDsSrs = (srsDs.GetType() == MgCoordinateSystemType.Arbitrary);
+                String dsSrsUnits = "";
+
+                if (arbitraryDsSrs)
+                    dsSrsUnits = srsDs.GetUnits();
+
+                // exclude layer if:
+                //  the map is non-arbitrary and the layer is arbitrary or vice-versa
+                //     or
+                //  layer and map are both arbitrary but have different units
+                //
+                if ((arbitraryDsSrs != arbitraryMapSrs) || (arbitraryDsSrs && (dsSrsUnits != mapSrsUnits)))
+                {
+                    excludedLayers++;
+                    continue;
+                }
+
+                // calculate distance in the data source SRS units
+                //
+                double dist = srsDs.ConvertMetersToCoordinateSystemUnits(distance);
+
+                // calculate great circle unless data source srs is arbitrary
+                MgCoordinateSystemMeasure measure;
+                if (!arbitraryDsSrs)
+                    measure = srsDs.GetMeasure();
+                else
+                    measure = null;
+
+                // create a SRS transformer if necessary
+                MgCoordinateSystemTransform srsXform;
+                if (!srsDefDs.Equals(srsDefMap))
+                    srsXform = srsFactory.GetTransform(srsDs, srsMap);
+                else
+                    srsXform = null;
+
+                String featureClassName = selLayer.GetFeatureClassName();
+                String filter = sel.GenerateFilter(selLayer, featureClassName);
+                if (filter == null || filter.Length == 0)
+                    continue;
+
+                MgFeatureQueryOptions query = new MgFeatureQueryOptions();
+                query.SetFilter(filter);
+
+                MgResourceIdentifier featureSource = new MgResourceIdentifier(selLayer.GetFeatureSourceId());
+
+                MgFeatureReader features = _featSvc.SelectFeatures(featureSource, featureClassName, query);
+
+                if (features.ReadNext())
+                {
+                    MgClassDefinition classDef = features.GetClassDefinition();
+                    String geomPropName = classDef.GetDefaultGeometryPropertyName();
+
+                    do
+                    {
+                        MgByteReader geomReader = features.GetGeometry(geomPropName);
+                        MgGeometry geom = agfRW.Read(geomReader);
+
+                        if (!chkMergeBuffers.Checked)
+                        {
+                            geomBuffer = geom.Buffer(dist, measure);
+                            if (geomBuffer != null)
+                            {
+                                if (srsXform != null)
+                                    geomBuffer = (MgGeometry)geomBuffer.Transform(srsXform);
+                                AddFeatureToCollection(propCollection, agfRW, featId++, geomBuffer);
+                                bufferFeatures++;
+                            }
+                        }
+                        else
+                        {
+                            if (srsXform != null)
+                                geom = (MgGeometry)geom.Transform(srsXform);
+                            inputGeometries.Add(geom);
+                        }
+                    }
+                    while (features.ReadNext());
+
+                    features.Close();
+                }
+            }
+
+            if (chkMergeBuffers.Checked)
+            {
+                if (inputGeometries.GetCount() > 0)
+                {
+                    double dist = srsMap.ConvertMetersToCoordinateSystemUnits(distance);
+                    MgCoordinateSystemMeasure measure;
+                    if (!arbitraryMapSrs)
+                        measure = srsMap.GetMeasure();
+                    else
+                        measure = null;
+
+                    MgGeometryFactory geomFactory = new MgGeometryFactory();
+                    geomBuffer = geomFactory.CreateMultiGeometry(inputGeometries).Buffer(dist, measure);
+                    if (geomBuffer != null)
+                    {
+                        AddFeatureToCollection(propCollection, agfRW, featId, geomBuffer);
+                        bufferFeatures = 1;
+                    }
+                }
+            }
+
+            if (propCollection.GetCount() > 0)
+            {
+                commands.Add(new MgInsertFeatures("BufferSchema:Buffer", propCollection));
+
+                //Insert the features in the temporary data source
+                //
+                ReleaseReader(_featSvc.UpdateFeatures(fsId, commands, false), commands);
+            }
+
+            // Save the new map state
+            //
+            layer.ForceRefresh();
+            _viewer.RefreshMap();
+
+            //build report message
+            MessageBox.Show("Buffer layer (" + txtBufferLayer.Text + ") " + (newBuffer ? "created" : "updated"));
+        }
+
+        private string[] GetLayerNames()
+        {
+            var items = new List<string>();
+            foreach (var it in lstLayers.Items)
+            {
+                items.Add(it.ToString());
+            }
+            return items.ToArray();
+        }
+
+        static string ToHtmlColor(Color color)
+        {
+            return String.Format("{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
+        }
+
+        static MgLayerBase FindLayer(MgLayerCollection layers, String layerName)
+        {
+            MgLayerBase layer = null;
+            int i = 0;
+            for (i = 0; i < layers.GetCount(); i++)
+            {
+                MgLayerBase layer1 = layers.GetItem(i);
+
+                if (layer1.GetName() == layerName)
+                {
+                    layer = layer1;
+                    break;
+                }
+            }
+            return layer;
+        }
+
+        static string GetMapSrs(MgMapBase map)
+        {
+            try
+            {
+                String srs = map.GetMapSRS();
+                if (srs != "")
+                    return srs;
+            }
+            catch (MgException e)
+            {
+            }
+
+            //No SRS, set to ArbitrayXY meters
+            //
+            return "LOCALCS[\"Non-Earth (Meter)\",LOCAL_DATUM[\"Local Datum\",0],UNIT[\"Meter\", 1],AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]]";
+        }
+
+        static void ClearDataSource(MgFeatureService featSvc, MgResourceIdentifier fsId, String featureName)
+        {
+            MgDeleteFeatures deleteCmd = new MgDeleteFeatures(featureName, "ID >= 0");
+            MgFeatureCommandCollection commands = new MgFeatureCommandCollection();
+            commands.Add(deleteCmd);
+            featSvc.UpdateFeatures(fsId, commands, false);
+        }
+
+        static void ReleaseReader(MgPropertyCollection res, MgFeatureCommandCollection commands)
+        {
+            if (res == null)
+                return;
+
+            for (int i = 0; i < res.GetCount(); i++)
+            {
+                MgFeatureCommand cmd = commands.GetItem(i);
+                if (cmd is MgInsertFeatures)
+                {
+                    MgFeatureProperty resProp = res.GetItem(i) as MgFeatureProperty;
+                    if (resProp != null)
+                    {
+                        MgFeatureReader reader = resProp.GetValue() as MgFeatureReader;
+                        if (reader == null)
+                            return;
+                        reader.Close();
+                    }
+                }
+            }
+        }
+
+        static void AddFeatureToCollection(MgBatchPropertyCollection propCollection, MgAgfReaderWriter agfRW, int featureId, MgGeometry featureGeom)
+        {
+            MgPropertyCollection bufferProps = new MgPropertyCollection();
+            MgInt32Property idProp = new MgInt32Property("ID", featureId);
+            bufferProps.Add(idProp);
+            MgByteReader geomReader = agfRW.Write(featureGeom);
+            MgGeometryProperty geomProp = new MgGeometryProperty("GEOM", geomReader);
+            bufferProps.Add(geomProp);
+            propCollection.Add(bufferProps);
+        }
+    }
+
+    public enum StockPattern
+    {
+        Solid,
+        Net,
+        Line,
+        Line_45,
+        Line_90,
+        Line_135,
+        Square,
+        Box,
+        Cross,
+        Dash,
+        Dolmit,
+        Hex,
+        Sacncr,
+        Steel
+    }
+}

Copied: trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.resx (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgBufferControlImpl.resx)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.resx	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.resx	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="colorPicker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
\ No newline at end of file

Copied: trunk/MgDev/Desktop/MapViewer/MgComponent.cs (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgComponent.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgComponent.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgComponent.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,216 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+using System.Windows.Forms;
+using System.Drawing;
+using System.Diagnostics;
+
+namespace OSGeo.MapGuide.Viewer
+{
+    /// <summary>
+    /// The base class of all viewer components. This is analogous to a command in the MapGuide
+    /// AJAX viewer and a widget in the Fusion viewer.
+    /// </summary>
+    [ToolboxItem(false)]
+    public class MgComponent : Component
+    {
+        private IMapViewer _viewer;
+
+        /// <summary>
+        /// Gets whether to disable invocation entry points (eg. buttons, menus, etc) to this component when the
+        /// viewer is busy
+        /// </summary>
+        [Category("MapGuide Component Properties")]
+        [Description("Disables this component while the map is loading")]
+        public virtual bool DisableWhenMapIsLoading { get { return true; } }
+
+        /// <summary>
+        /// Gets or sets the description of this component
+        /// </summary>
+        [Category("MapGuide Component Properties")]
+        [Description("The description of this component")]
+        public string Label { get; set; }
+
+        /// <summary>
+        /// Gets or sets the tooltip text of this component
+        /// </summary>
+        [Category("MapGuide Component Properties")]
+        [Description("The tooltip text of this component")]
+        public string ToolTipText { get; set; }
+
+        /// <summary>
+        /// The icon for this component
+        /// </summary>
+        [Category("MapGuide Component Properties")]
+        [Description("The icon for this component")]
+        public Image Icon { get; set; }
+
+        /// <summary>
+        /// Gets or sets the view instance to subscribe events to
+        /// </summary>
+        [Category("MapGuide Component Properties")]
+        [Description("The viewer instance to subscribe events to")]
+        public IMapViewer Viewer
+        {
+            get { return _viewer; }
+            set
+            {
+                if (_viewer != null)
+                    UnsubscribeViewerEvents(_viewer);
+                _viewer = value;
+                SubscribeViewerEvents(_viewer);
+            }
+        }
+
+        /// <summary>
+        /// Subscribes to viewer events
+        /// </summary>
+        /// <param name="viewer"></param>
+        protected virtual void SubscribeViewerEvents(IMapViewer viewer)
+        {
+            if (viewer != null)
+                viewer.PropertyChanged += OnViewerPropertyChanged;
+        }
+
+        public event ViewerBusyStateEventHandler ViewerBusyStateChanged;
+
+        void OnViewerPropertyChanged(object sender, PropertyChangedEventArgs e)
+        {
+            if (e.PropertyName == "IsBusy")
+            {
+                var busy = this.Viewer.IsBusy;
+                Trace.TraceInformation("Dispatching busy state event to " + _listeners.Count + " listeners");
+                foreach (var l in _listeners)
+                    l.SetBusy(busy);
+            }
+        }
+
+        /// <summary>
+        /// Unsubscribes events from the specified viewer instance
+        /// </summary>
+        /// <param name="viewer"></param>
+        protected virtual void UnsubscribeViewerEvents(IMapViewer viewer)
+        {
+            if (viewer != null)
+                viewer.PropertyChanged -= OnViewerPropertyChanged;
+        }
+
+        private List<IMapViewerBusyStateListener> _listeners = new List<IMapViewerBusyStateListener>();
+
+        public void AddListener(IMapViewerBusyStateListener listener)
+        {
+            _listeners.Add(listener);
+        }
+
+        public void RemoveListener(IMapViewerBusyStateListener listener)
+        {
+            _listeners.Remove(listener);
+        }
+
+        /// <summary>
+        /// Invokes this component
+        /// </summary>
+        public virtual void Invoke() 
+        {
+            
+        }
+    }
+
+    public delegate void ViewerBusyStateEventHandler(bool busy);
+
+    public interface IMapViewerBusyStateListener
+    {
+        void SetBusy(bool busy);
+    }
+
+    /// <summary>
+    /// Indicates the target a UI-based component should display its UI view in
+    /// </summary>
+    public enum MgViewerTarget
+    {
+        /// <summary>
+        /// Display the UI view within the specified parent container
+        /// </summary>
+        ParentContainer,
+        /// <summary>
+        /// Display the UI view within a new window
+        /// </summary>
+        NewWindow
+    }
+
+    /// <summary>
+    /// The base class of all UI-based components
+    /// </summary>
+    [ToolboxItem(false)]
+    public class MgViewerComponent : MgComponent
+    {
+        protected MgViewerComponent()
+        {
+            this.ParentContainer = null;
+            this.Target = MgViewerTarget.NewWindow;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        [Category("MapGuide Component Properties")]
+        [Description("The control which will house this component")]
+        public Control ParentContainer
+        {
+            get;
+            set;
+        }
+
+        private MgViewerTarget _target;
+
+        /// <summary>
+        /// Gets or sets the target that this component should display its UI view in
+        /// </summary>
+        [Category("MapGuide Component Properties")]
+        [DefaultValue(MgViewerTarget.NewWindow)]
+        [Description("Target that this component should display its UI view in")]
+        public MgViewerTarget Target
+        {
+            get { return _target; }
+            set
+            {
+                if (value == MgViewerTarget.ParentContainer && this.ParentContainer == null)
+                    throw new ArgumentException("Must specify a parent container");
+                _target = value;
+            }
+        }
+
+        /// <summary>
+        /// Creates the associated view. Must be overridden by subclasses
+        /// </summary>
+        /// <returns></returns>
+        protected virtual MgControlImpl CreateControlImpl() { throw new NotImplementedException(); }
+
+        public override void Invoke()
+        {
+            var control = CreateControlImpl();
+            control.Dock = DockStyle.Fill;
+            if (this.Target == MgViewerTarget.ParentContainer)
+            {
+                this.ParentContainer.Controls.Clear();
+                this.ParentContainer.Controls.Add(control);
+            }
+            else //New Window
+            {
+                var form = new Form();
+                Rectangle screenRectangle = form.RectangleToScreen(form.ClientRectangle);
+                int titleHeight = screenRectangle.Top - form.Top;
+                form.Width = control.PreferredSize.Width;
+                form.Height = control.PreferredSize.Height + titleHeight + 10; //HACK: height calculation is imperfect, so pad out
+                form.Text = control.Title;
+                form.Controls.Add(control);
+
+                if (control.ModalWindow)
+                    form.ShowDialog();
+                else
+                    form.Show();
+            }
+        }
+    }
+}

Copied: trunk/MgDev/Desktop/MapViewer/MgControlImpl.cs (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgControlImpl.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgControlImpl.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgControlImpl.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Forms;
+using System.ComponentModel;
+
+namespace OSGeo.MapGuide.Viewer
+{
+    /// <summary>
+    /// Base class for views show by their associated <see cref="T:OSGeo.MapGuide.Viewer.MgViewerComponent"/> instances
+    /// </summary>
+    [ToolboxItem(false)]
+    public class MgControlImpl : UserControl
+    {
+        /// <summary>
+        /// Gets or set the title to show if this view is shown in a new window
+        /// </summary>
+        public virtual string Title { get; set; }
+
+        protected MgControlImpl() { this.ModalWindow = false; }
+
+        /// <summary>
+        /// Gets whether to show as a modal window if parent component chooses to show this component
+        /// in a new window. Only applies if parent component shows this component in a new window
+        /// </summary>
+        public virtual bool ModalWindow { get; set; }
+    }
+}

Copied: trunk/MgDev/Desktop/MapViewer/MgInvokeComponent.cs (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgInvokeComponent.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgInvokeComponent.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgInvokeComponent.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,107 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Forms;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms.Design;
+using System.Diagnostics;
+
+namespace OSGeo.MapGuide.Viewer
+{
+    /// <summary>
+    /// A specialized instance of <see cref="T:System.Windows.Forms.ToolStripButton"/> that can
+    /// invoke the assigned <see cref="T:OSGeo.MapGuide.Viewer.MgComponent"/> instance.
+    /// </summary>
+    [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip)]
+    public class MgInvokeComponentButton : ToolStripButton, IMapViewerBusyStateListener
+    {
+        private MgComponent _component;
+
+        /// <summary>
+        /// Gets or sets the target component to be invoked
+        /// </summary>
+        [Category("MapGuide Component Properties")]
+        [Description("The target component to invoke when this component is clicked. All other UI properties are inherited from this compoent")]
+        public MgComponent TargetComponent
+        {
+            get { return _component; }
+            set 
+            {
+                if (_component != null)
+                    _component.RemoveListener(this);
+                _component = value;
+                if (_component != null)
+                {
+                    base.ToolTipText = _component.ToolTipText;
+                    base.Text = _component.Label;
+                    base.Image = _component.Icon;
+                    _component.AddListener(this);
+                }
+            }
+        }
+
+        protected override void OnClick(EventArgs e)
+        {
+            if (this.TargetComponent == null)
+                throw new InvalidOperationException("No target component assigned to this component");
+
+            this.TargetComponent.Invoke();
+
+            base.OnClick(e);
+        }
+
+        public void SetBusy(bool busy)
+        {
+            this.Enabled = !busy;
+        }
+    }
+
+    /// <summary>
+    /// A specialized instance of <see cref="T:System.Windows.Forms.ToolStripMenuItem"/> that can
+    /// invoke the assigned <see cref="T:OSGeo.MapGuide.Viewer.MgComponent"/> instance.
+    /// </summary>
+    [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ContextMenuStrip | ToolStripItemDesignerAvailability.MenuStrip)]
+    public class MgInvokeComponentMenuStripItem : ToolStripMenuItem, IMapViewerBusyStateListener
+    {
+        private MgComponent _component;
+
+        /// <summary>
+        /// Gets or sets the target component to be invoked
+        /// </summary>
+        [Category("MapGuide Component Properties")]
+        [Description("The target component to invoke when this component is clicked. All other UI properties are inherited from this compoent")]
+        public MgComponent TargetComponent
+        {
+            get { return _component; }
+            set
+            {
+                if (_component != null)
+                    _component.RemoveListener(this);
+                _component = value;
+                if (_component != null)
+                {
+                    base.ToolTipText = _component.ToolTipText;
+                    base.Text = _component.Label;
+                    base.Image = _component.Icon;
+                    _component.AddListener(this);
+                }
+            }
+        }
+
+        protected override void OnClick(EventArgs e)
+        {
+            if (this.TargetComponent == null)
+                throw new InvalidOperationException("No target component assigned to this component");
+
+            this.TargetComponent.Invoke();
+
+            base.OnClick(e);
+        }
+
+        public void SetBusy(bool busy)
+        {
+            this.Enabled = !busy;
+        }
+    }
+}

Deleted: trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.Designer.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.Designer.cs	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.Designer.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -1,155 +0,0 @@
-namespace OSGeo.MapGuide.Viewer
-{
-    partial class MgLineMeasureControl
-    {
-        /// <summary> 
-        /// Required designer variable.
-        /// </summary>
-        private System.ComponentModel.IContainer components = null;
-
-        /// <summary> 
-        /// Clean up any resources being used.
-        /// </summary>
-        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing && (components != null))
-            {
-                components.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-
-        #region Component Designer generated code
-
-        /// <summary> 
-        /// Required method for Designer support - do not modify 
-        /// the contents of this method with the code editor.
-        /// </summary>
-        private void InitializeComponent()
-        {
-            this.label1 = new System.Windows.Forms.Label();
-            this.lstSegments = new System.Windows.Forms.ListBox();
-            this.label2 = new System.Windows.Forms.Label();
-            this.lblUnits = new System.Windows.Forms.Label();
-            this.label3 = new System.Windows.Forms.Label();
-            this.cmbUnits = new System.Windows.Forms.ComboBox();
-            this.btnStart = new System.Windows.Forms.Button();
-            this.groupBox1 = new System.Windows.Forms.GroupBox();
-            this.groupBox1.SuspendLayout();
-            this.SuspendLayout();
-            // 
-            // label1
-            // 
-            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-            this.label1.AutoSize = true;
-            this.label1.Location = new System.Drawing.Point(15, 297);
-            this.label1.Name = "label1";
-            this.label1.Size = new System.Drawing.Size(157, 13);
-            this.label1.TabIndex = 0;
-            this.label1.Text = "Click \"Start\" to begin measuring";
-            // 
-            // lstSegments
-            // 
-            this.lstSegments.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.lstSegments.FormattingEnabled = true;
-            this.lstSegments.Location = new System.Drawing.Point(3, 16);
-            this.lstSegments.Name = "lstSegments";
-            this.lstSegments.Size = new System.Drawing.Size(206, 192);
-            this.lstSegments.TabIndex = 1;
-            // 
-            // label2
-            // 
-            this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-            this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(15, 270);
-            this.label2.Name = "label2";
-            this.label2.Size = new System.Drawing.Size(79, 13);
-            this.label2.TabIndex = 2;
-            this.label2.Text = "Total Distance:";
-            // 
-            // lblUnits
-            // 
-            this.lblUnits.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-            this.lblUnits.AutoSize = true;
-            this.lblUnits.Location = new System.Drawing.Point(100, 270);
-            this.lblUnits.Name = "lblUnits";
-            this.lblUnits.Size = new System.Drawing.Size(0, 13);
-            this.lblUnits.TabIndex = 3;
-            // 
-            // label3
-            // 
-            this.label3.AutoSize = true;
-            this.label3.Location = new System.Drawing.Point(15, 17);
-            this.label3.Name = "label3";
-            this.label3.Size = new System.Drawing.Size(34, 13);
-            this.label3.TabIndex = 4;
-            this.label3.Text = "Units:";
-            // 
-            // cmbUnits
-            // 
-            this.cmbUnits.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.cmbUnits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-            this.cmbUnits.FormattingEnabled = true;
-            this.cmbUnits.Location = new System.Drawing.Point(97, 14);
-            this.cmbUnits.Name = "cmbUnits";
-            this.cmbUnits.Size = new System.Drawing.Size(127, 21);
-            this.cmbUnits.TabIndex = 5;
-            this.cmbUnits.SelectedIndexChanged += new System.EventHandler(this.cmbUnits_SelectedIndexChanged);
-            // 
-            // btnStart
-            // 
-            this.btnStart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-            this.btnStart.Location = new System.Drawing.Point(18, 325);
-            this.btnStart.Name = "btnStart";
-            this.btnStart.Size = new System.Drawing.Size(82, 23);
-            this.btnStart.TabIndex = 6;
-            this.btnStart.Text = "Start";
-            this.btnStart.UseVisualStyleBackColor = true;
-            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
-            // 
-            // groupBox1
-            // 
-            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
-            | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.groupBox1.Controls.Add(this.lstSegments);
-            this.groupBox1.Location = new System.Drawing.Point(15, 41);
-            this.groupBox1.Name = "groupBox1";
-            this.groupBox1.Size = new System.Drawing.Size(212, 211);
-            this.groupBox1.TabIndex = 7;
-            this.groupBox1.TabStop = false;
-            this.groupBox1.Text = "Segments";
-            // 
-            // MgLineMeasureControl
-            // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.Controls.Add(this.groupBox1);
-            this.Controls.Add(this.btnStart);
-            this.Controls.Add(this.cmbUnits);
-            this.Controls.Add(this.label3);
-            this.Controls.Add(this.lblUnits);
-            this.Controls.Add(this.label2);
-            this.Controls.Add(this.label1);
-            this.Name = "MgLineMeasureControl";
-            this.Size = new System.Drawing.Size(247, 360);
-            this.groupBox1.ResumeLayout(false);
-            this.ResumeLayout(false);
-            this.PerformLayout();
-
-        }
-
-        #endregion
-
-        private System.Windows.Forms.Label label1;
-        private System.Windows.Forms.ListBox lstSegments;
-        private System.Windows.Forms.Label label2;
-        private System.Windows.Forms.Label lblUnits;
-        private System.Windows.Forms.Label label3;
-        private System.Windows.Forms.ComboBox cmbUnits;
-        private System.Windows.Forms.Button btnStart;
-        private System.Windows.Forms.GroupBox groupBox1;
-    }
-}

Deleted: trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.cs	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -1,133 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.Data;
-using System.Text;
-using System.Windows.Forms;
-
-namespace OSGeo.MapGuide.Viewer
-{
-    public partial class MgLineMeasureControl : UserControl
-    {
-        private IMapViewer _viewer;
-        private MgCoordinateSystem _mapCs;
-        private BindingList<MeasuredLineSegment> _segments;
-
-        public MgLineMeasureControl(IMapViewer viewer, MeasurementUnit preferredUnit)
-        {
-            InitializeComponent();
-            _viewer = viewer;
-            _segments = new BindingList<MeasuredLineSegment>();
-            cmbUnits.DataSource = Enum.GetValues(typeof(MeasurementUnit));
-            cmbUnits.SelectedItem = preferredUnit;
-            lstSegments.DataSource = _segments;
-            _mapCs = _viewer.GetProvider().GetMapCoordinateSystem();
-        }
-
-        private void btnStart_Click(object sender, EventArgs e)
-        {
-            btnStart.Enabled = false;
-            _segments.Clear();
-            _viewer.DigitizeLineString((coordinates) => //Completed
-            {
-                btnStart.Enabled = true;
-            }, (x1, y1, x2, y2) => //Segment completed
-            {
-                double dist = 0.0;
-                if (_mapCs.GetType() == MgCoordinateSystemType.Geographic)
-                    dist = _mapCs.MeasureGreatCircleDistance(x1, y1, x2, y2);
-                else
-                    dist = _mapCs.MeasureEuclideanDistance(x1, y1, x2, y2);
-
-                //Convert this distance to meters
-                dist = _mapCs.ConvertCoordinateSystemUnitsToMeters(dist);
-                //Add to list of line segments
-                _segments.Add(new MeasuredLineSegment() { MapDistanceMeters = dist, Units = (MeasurementUnit)cmbUnits.SelectedItem });
-
-                lblUnits.Text = TotalUnits(_segments).ToString();
-            });
-        }
-
-        private static double TotalUnits(IEnumerable<MeasuredLineSegment> segments)
-        {
-            double total = 0.0;
-            foreach (var seg in segments)
-            {
-                total += seg.DisplayUnits;
-            }
-            return total;
-        }
-
-        private void cmbUnits_SelectedIndexChanged(object sender, EventArgs e)
-        {
-            //Update segments units, then total
-            foreach (var seg in _segments)
-            {
-                seg.Units = (MeasurementUnit)cmbUnits.SelectedItem;
-            }
-            lblUnits.Text = TotalUnits(_segments).ToString(); 
-        }
-    }
-
-    public enum MeasurementUnit
-    {
-        Feet,
-        Meters,
-        Kilometers,
-        Miles
-    }
-
-    public class MeasuredLineSegment : INotifyPropertyChanged
-    {
-        public double MapDistanceMeters { get; set; }
-
-        private MeasurementUnit _units;
-
-        public MeasurementUnit Units
-        {
-            get { return _units; }
-            set 
-            {
-                if (!value.Equals(_units))
-                {
-                    _units = value;
-                    var h = this.PropertyChanged;
-                    if (h != null) 
-                    {
-                        h(this, new PropertyChangedEventArgs("Units"));
-                        h(this, new PropertyChangedEventArgs("DisplayUnits"));
-                    }
-                }
-            }
-        }
-
-        const double M_TO_KM = 0.001;
-        const double M_TO_MI = 0.000621371192;
-
-        public double DisplayUnits
-        {
-            get
-            {
-                var dist = this.MapDistanceMeters;
-                switch (this.Units)
-                {
-                    case MeasurementUnit.Kilometers:
-                        dist *= M_TO_KM;
-                        break;
-                    case MeasurementUnit.Miles:
-                        dist *= M_TO_MI;
-                        break;
-                }
-                return dist;
-            }
-        }
-
-        public override string ToString()
-        {
-            return string.Format("{0} {1}", this.DisplayUnits, this.Units);
-        }
-
-        public event PropertyChangedEventHandler PropertyChanged;
-    }
-}

Deleted: trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.resx
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.resx	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/MgLineMeasureControl.resx	2012-05-03 14:38:06 UTC (rev 6609)
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-</root>

Copied: trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.Designer.cs (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.Designer.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.Designer.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.Designer.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,155 @@
+namespace OSGeo.MapGuide.Viewer
+{
+    partial class MgLineMeasureControlImpl
+    {
+        /// <summary> 
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.lstSegments = new System.Windows.Forms.ListBox();
+            this.label2 = new System.Windows.Forms.Label();
+            this.lblUnits = new System.Windows.Forms.Label();
+            this.label3 = new System.Windows.Forms.Label();
+            this.cmbUnits = new System.Windows.Forms.ComboBox();
+            this.btnStart = new System.Windows.Forms.Button();
+            this.groupBox1 = new System.Windows.Forms.GroupBox();
+            this.groupBox1.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(15, 297);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(157, 13);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "Click \"Start\" to begin measuring";
+            // 
+            // lstSegments
+            // 
+            this.lstSegments.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.lstSegments.FormattingEnabled = true;
+            this.lstSegments.Location = new System.Drawing.Point(3, 16);
+            this.lstSegments.Name = "lstSegments";
+            this.lstSegments.Size = new System.Drawing.Size(206, 192);
+            this.lstSegments.TabIndex = 1;
+            // 
+            // label2
+            // 
+            this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(15, 270);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(79, 13);
+            this.label2.TabIndex = 2;
+            this.label2.Text = "Total Distance:";
+            // 
+            // lblUnits
+            // 
+            this.lblUnits.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.lblUnits.AutoSize = true;
+            this.lblUnits.Location = new System.Drawing.Point(100, 270);
+            this.lblUnits.Name = "lblUnits";
+            this.lblUnits.Size = new System.Drawing.Size(0, 13);
+            this.lblUnits.TabIndex = 3;
+            // 
+            // label3
+            // 
+            this.label3.AutoSize = true;
+            this.label3.Location = new System.Drawing.Point(15, 17);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(34, 13);
+            this.label3.TabIndex = 4;
+            this.label3.Text = "Units:";
+            // 
+            // cmbUnits
+            // 
+            this.cmbUnits.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbUnits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbUnits.FormattingEnabled = true;
+            this.cmbUnits.Location = new System.Drawing.Point(97, 14);
+            this.cmbUnits.Name = "cmbUnits";
+            this.cmbUnits.Size = new System.Drawing.Size(127, 21);
+            this.cmbUnits.TabIndex = 5;
+            this.cmbUnits.SelectedIndexChanged += new System.EventHandler(this.cmbUnits_SelectedIndexChanged);
+            // 
+            // btnStart
+            // 
+            this.btnStart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.btnStart.Location = new System.Drawing.Point(18, 325);
+            this.btnStart.Name = "btnStart";
+            this.btnStart.Size = new System.Drawing.Size(82, 23);
+            this.btnStart.TabIndex = 6;
+            this.btnStart.Text = "Start";
+            this.btnStart.UseVisualStyleBackColor = true;
+            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
+            // 
+            // groupBox1
+            // 
+            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.groupBox1.Controls.Add(this.lstSegments);
+            this.groupBox1.Location = new System.Drawing.Point(15, 41);
+            this.groupBox1.Name = "groupBox1";
+            this.groupBox1.Size = new System.Drawing.Size(212, 211);
+            this.groupBox1.TabIndex = 7;
+            this.groupBox1.TabStop = false;
+            this.groupBox1.Text = "Segments";
+            // 
+            // MgLineMeasureControl
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.groupBox1);
+            this.Controls.Add(this.btnStart);
+            this.Controls.Add(this.cmbUnits);
+            this.Controls.Add(this.label3);
+            this.Controls.Add(this.lblUnits);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.label1);
+            this.Name = "MgLineMeasureControl";
+            this.Size = new System.Drawing.Size(247, 360);
+            this.groupBox1.ResumeLayout(false);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.ListBox lstSegments;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.Label lblUnits;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.ComboBox cmbUnits;
+        private System.Windows.Forms.Button btnStart;
+        private System.Windows.Forms.GroupBox groupBox1;
+    }
+}

Copied: trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.cs (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,134 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+
+namespace OSGeo.MapGuide.Viewer
+{
+    internal partial class MgLineMeasureControlImpl : MgControlImpl
+    {
+        private IMapViewer _viewer;
+        private MgCoordinateSystem _mapCs;
+        private BindingList<MeasuredLineSegment> _segments;
+
+        public MgLineMeasureControlImpl(IMapViewer viewer, MeasurementUnit preferredUnit)
+        {
+            InitializeComponent();
+            this.Title = Properties.Resources.TitleMeasure;
+            _viewer = viewer;
+            _segments = new BindingList<MeasuredLineSegment>();
+            cmbUnits.DataSource = Enum.GetValues(typeof(MeasurementUnit));
+            cmbUnits.SelectedItem = preferredUnit;
+            lstSegments.DataSource = _segments;
+            _mapCs = _viewer.GetProvider().GetMapCoordinateSystem();
+        }
+
+        private void btnStart_Click(object sender, EventArgs e)
+        {
+            btnStart.Enabled = false;
+            _segments.Clear();
+            _viewer.DigitizeLineString((coordinates) => //Completed
+            {
+                btnStart.Enabled = true;
+            }, (x1, y1, x2, y2) => //Segment completed
+            {
+                double dist = 0.0;
+                if (_mapCs.GetType() == MgCoordinateSystemType.Geographic)
+                    dist = _mapCs.MeasureGreatCircleDistance(x1, y1, x2, y2);
+                else
+                    dist = _mapCs.MeasureEuclideanDistance(x1, y1, x2, y2);
+
+                //Convert this distance to meters
+                dist = _mapCs.ConvertCoordinateSystemUnitsToMeters(dist);
+                //Add to list of line segments
+                _segments.Add(new MeasuredLineSegment() { MapDistanceMeters = dist, Units = (MeasurementUnit)cmbUnits.SelectedItem });
+
+                lblUnits.Text = TotalUnits(_segments).ToString();
+            });
+        }
+
+        private static double TotalUnits(IEnumerable<MeasuredLineSegment> segments)
+        {
+            double total = 0.0;
+            foreach (var seg in segments)
+            {
+                total += seg.DisplayUnits;
+            }
+            return total;
+        }
+
+        private void cmbUnits_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            //Update segments units, then total
+            foreach (var seg in _segments)
+            {
+                seg.Units = (MeasurementUnit)cmbUnits.SelectedItem;
+            }
+            lblUnits.Text = TotalUnits(_segments).ToString(); 
+        }
+    }
+
+    public enum MeasurementUnit
+    {
+        Feet,
+        Meters,
+        Kilometers,
+        Miles
+    }
+
+    public class MeasuredLineSegment : INotifyPropertyChanged
+    {
+        public double MapDistanceMeters { get; set; }
+
+        private MeasurementUnit _units;
+
+        public MeasurementUnit Units
+        {
+            get { return _units; }
+            set 
+            {
+                if (!value.Equals(_units))
+                {
+                    _units = value;
+                    var h = this.PropertyChanged;
+                    if (h != null) 
+                    {
+                        h(this, new PropertyChangedEventArgs("Units"));
+                        h(this, new PropertyChangedEventArgs("DisplayUnits"));
+                    }
+                }
+            }
+        }
+
+        const double M_TO_KM = 0.001;
+        const double M_TO_MI = 0.000621371192;
+
+        public double DisplayUnits
+        {
+            get
+            {
+                var dist = this.MapDistanceMeters;
+                switch (this.Units)
+                {
+                    case MeasurementUnit.Kilometers:
+                        dist *= M_TO_KM;
+                        break;
+                    case MeasurementUnit.Miles:
+                        dist *= M_TO_MI;
+                        break;
+                }
+                return dist;
+            }
+        }
+
+        public override string ToString()
+        {
+            return string.Format("{0} {1}", this.DisplayUnits, this.Units);
+        }
+
+        public event PropertyChangedEventHandler PropertyChanged;
+    }
+}

Copied: trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.resx (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.resx)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.resx	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.resx	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file

Copied: trunk/MgDev/Desktop/MapViewer/MgMeasureControl.cs (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgMeasureControl.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgMeasureControl.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgMeasureControl.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+
+namespace OSGeo.MapGuide.Viewer
+{
+    /// <summary>
+    /// A generic component for measuring
+    /// </summary>
+    [ToolboxItem(true)]
+    public class MgMeasureControl : MgViewerComponent
+    {
+        public MgMeasureControl()
+        {
+            this.Icon = Properties.Resources.measure;
+            this.Label = Properties.Resources.TitleMeasure;
+            this.MeasureMode = MeasureMode.Line;
+            this.PreferredUnits = MeasurementUnit.Meters;
+        }
+
+        protected override MgControlImpl CreateControlImpl()
+        {
+            switch (_measureMode)
+            {
+                case MeasureMode.Line:
+                    return new MgLineMeasureControlImpl(this.Viewer, this.PreferredUnits);
+                default:
+                    throw new NotImplementedException();
+            }
+        }
+
+        [Category("MapGuide Component Properties")]
+        [Description("The default units to measure in")]
+        [DefaultValue(MeasurementUnit.Meters)]
+        public MeasurementUnit PreferredUnits
+        {
+            get;
+            set;
+        }
+
+        private MeasureMode _measureMode;
+
+        [Category("MapGuide Component Properties")]
+        [DefaultValue(MeasureMode.Line)]
+        [Browsable(true)]
+        [Description("The mode of measurement")]
+        public MeasureMode MeasureMode
+        {
+            get { return _measureMode; }
+            set 
+            {
+                if (value == MeasureMode.Area)
+                    throw new NotImplementedException("This mode is not yet implemented");
+                _measureMode = value; 
+            }
+        }
+    }
+
+    /// <summary>
+    /// Defines the valid types of measurements that can be done by the <see cref="T:OSGeo.MapGuide.Viewer.MgMeasureControl"/> component
+    /// </summary>
+    public enum MeasureMode
+    {
+        /// <summary>
+        /// Measure distance by tracing 1 or more line segments
+        /// </summary>
+        Line,
+        /// <summary>
+        /// Measure area by tracing a polygon
+        /// </summary>
+        Area
+    }
+}

Deleted: trunk/MgDev/Desktop/MapViewer/MgQueryControl.Designer.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgQueryControl.Designer.cs	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/MgQueryControl.Designer.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -1,329 +0,0 @@
-namespace OSGeo.MapGuide.Viewer
-{
-    partial class MgQueryControl
-    {
-        /// <summary> 
-        /// Required designer variable.
-        /// </summary>
-        private System.ComponentModel.IContainer components = null;
-
-        /// <summary> 
-        /// Clean up any resources being used.
-        /// </summary>
-        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing && (components != null))
-            {
-                components.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-
-        #region Component Designer generated code
-
-        /// <summary> 
-        /// Required method for Designer support - do not modify 
-        /// the contents of this method with the code editor.
-        /// </summary>
-        private void InitializeComponent()
-        {
-            this.groupBox1 = new System.Windows.Forms.GroupBox();
-            this.label1 = new System.Windows.Forms.Label();
-            this.cmbLayer = new System.Windows.Forms.ComboBox();
-            this.groupBox2 = new System.Windows.Forms.GroupBox();
-            this.txtValue = new System.Windows.Forms.TextBox();
-            this.label4 = new System.Windows.Forms.Label();
-            this.cmbOperator = new System.Windows.Forms.ComboBox();
-            this.label3 = new System.Windows.Forms.Label();
-            this.cmbProperty = new System.Windows.Forms.ComboBox();
-            this.label2 = new System.Windows.Forms.Label();
-            this.chkPropFilterEnabled = new System.Windows.Forms.CheckBox();
-            this.groupBox3 = new System.Windows.Forms.GroupBox();
-            this.spatialFilterButtonPanel = new System.Windows.Forms.FlowLayoutPanel();
-            this.btnRectangle = new System.Windows.Forms.Button();
-            this.btnPolygon = new System.Windows.Forms.Button();
-            this.btnClear = new System.Windows.Forms.Button();
-            this.chkSpatialFilter = new System.Windows.Forms.CheckBox();
-            this.btnExecute = new System.Windows.Forms.Button();
-            this.label5 = new System.Windows.Forms.Label();
-            this.numResults = new System.Windows.Forms.NumericUpDown();
-            this.groupBox1.SuspendLayout();
-            this.groupBox2.SuspendLayout();
-            this.groupBox3.SuspendLayout();
-            this.spatialFilterButtonPanel.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.numResults)).BeginInit();
-            this.SuspendLayout();
-            // 
-            // groupBox1
-            // 
-            this.groupBox1.Controls.Add(this.label1);
-            this.groupBox1.Controls.Add(this.cmbLayer);
-            this.groupBox1.Dock = System.Windows.Forms.DockStyle.Top;
-            this.groupBox1.Location = new System.Drawing.Point(0, 0);
-            this.groupBox1.Name = "groupBox1";
-            this.groupBox1.Size = new System.Drawing.Size(266, 82);
-            this.groupBox1.TabIndex = 0;
-            this.groupBox1.TabStop = false;
-            this.groupBox1.Text = "Layer";
-            // 
-            // label1
-            // 
-            this.label1.AutoSize = true;
-            this.label1.Location = new System.Drawing.Point(16, 20);
-            this.label1.Name = "label1";
-            this.label1.Size = new System.Drawing.Size(75, 13);
-            this.label1.TabIndex = 1;
-            this.label1.Text = "Select a Layer";
-            // 
-            // cmbLayer
-            // 
-            this.cmbLayer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.cmbLayer.DisplayMember = "Name";
-            this.cmbLayer.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-            this.cmbLayer.FormattingEnabled = true;
-            this.cmbLayer.Location = new System.Drawing.Point(16, 45);
-            this.cmbLayer.Name = "cmbLayer";
-            this.cmbLayer.Size = new System.Drawing.Size(231, 21);
-            this.cmbLayer.TabIndex = 0;
-            this.cmbLayer.SelectedIndexChanged += new System.EventHandler(this.cmbLayer_SelectedIndexChanged);
-            // 
-            // groupBox2
-            // 
-            this.groupBox2.Controls.Add(this.txtValue);
-            this.groupBox2.Controls.Add(this.label4);
-            this.groupBox2.Controls.Add(this.cmbOperator);
-            this.groupBox2.Controls.Add(this.label3);
-            this.groupBox2.Controls.Add(this.cmbProperty);
-            this.groupBox2.Controls.Add(this.label2);
-            this.groupBox2.Controls.Add(this.chkPropFilterEnabled);
-            this.groupBox2.Dock = System.Windows.Forms.DockStyle.Top;
-            this.groupBox2.Location = new System.Drawing.Point(0, 82);
-            this.groupBox2.Name = "groupBox2";
-            this.groupBox2.Size = new System.Drawing.Size(266, 187);
-            this.groupBox2.TabIndex = 1;
-            this.groupBox2.TabStop = false;
-            this.groupBox2.Text = "Property Filter";
-            // 
-            // txtValue
-            // 
-            this.txtValue.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.txtValue.Location = new System.Drawing.Point(16, 145);
-            this.txtValue.Name = "txtValue";
-            this.txtValue.Size = new System.Drawing.Size(231, 20);
-            this.txtValue.TabIndex = 6;
-            // 
-            // label4
-            // 
-            this.label4.AutoSize = true;
-            this.label4.Location = new System.Drawing.Point(16, 129);
-            this.label4.Name = "label4";
-            this.label4.Size = new System.Drawing.Size(34, 13);
-            this.label4.TabIndex = 5;
-            this.label4.Text = "Value";
-            // 
-            // cmbOperator
-            // 
-            this.cmbOperator.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.cmbOperator.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-            this.cmbOperator.FormattingEnabled = true;
-            this.cmbOperator.Location = new System.Drawing.Point(16, 101);
-            this.cmbOperator.Name = "cmbOperator";
-            this.cmbOperator.Size = new System.Drawing.Size(231, 21);
-            this.cmbOperator.TabIndex = 4;
-            // 
-            // label3
-            // 
-            this.label3.AutoSize = true;
-            this.label3.Location = new System.Drawing.Point(16, 85);
-            this.label3.Name = "label3";
-            this.label3.Size = new System.Drawing.Size(48, 13);
-            this.label3.TabIndex = 3;
-            this.label3.Text = "Operator";
-            // 
-            // cmbProperty
-            // 
-            this.cmbProperty.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.cmbProperty.DisplayMember = "Name";
-            this.cmbProperty.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-            this.cmbProperty.FormattingEnabled = true;
-            this.cmbProperty.Location = new System.Drawing.Point(16, 60);
-            this.cmbProperty.Name = "cmbProperty";
-            this.cmbProperty.Size = new System.Drawing.Size(231, 21);
-            this.cmbProperty.TabIndex = 2;
-            // 
-            // label2
-            // 
-            this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(16, 44);
-            this.label2.Name = "label2";
-            this.label2.Size = new System.Drawing.Size(46, 13);
-            this.label2.TabIndex = 1;
-            this.label2.Text = "Property";
-            // 
-            // chkPropFilterEnabled
-            // 
-            this.chkPropFilterEnabled.AutoSize = true;
-            this.chkPropFilterEnabled.Location = new System.Drawing.Point(19, 20);
-            this.chkPropFilterEnabled.Name = "chkPropFilterEnabled";
-            this.chkPropFilterEnabled.Size = new System.Drawing.Size(65, 17);
-            this.chkPropFilterEnabled.TabIndex = 0;
-            this.chkPropFilterEnabled.Text = "Enabled";
-            this.chkPropFilterEnabled.UseVisualStyleBackColor = true;
-            // 
-            // groupBox3
-            // 
-            this.groupBox3.Controls.Add(this.spatialFilterButtonPanel);
-            this.groupBox3.Controls.Add(this.chkSpatialFilter);
-            this.groupBox3.Dock = System.Windows.Forms.DockStyle.Top;
-            this.groupBox3.Location = new System.Drawing.Point(0, 269);
-            this.groupBox3.Name = "groupBox3";
-            this.groupBox3.Size = new System.Drawing.Size(266, 119);
-            this.groupBox3.TabIndex = 2;
-            this.groupBox3.TabStop = false;
-            this.groupBox3.Text = "Spatial Filter";
-            // 
-            // spatialFilterButtonPanel
-            // 
-            this.spatialFilterButtonPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
-            | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.spatialFilterButtonPanel.Controls.Add(this.btnRectangle);
-            this.spatialFilterButtonPanel.Controls.Add(this.btnPolygon);
-            this.spatialFilterButtonPanel.Controls.Add(this.btnClear);
-            this.spatialFilterButtonPanel.Location = new System.Drawing.Point(19, 43);
-            this.spatialFilterButtonPanel.Name = "spatialFilterButtonPanel";
-            this.spatialFilterButtonPanel.Size = new System.Drawing.Size(228, 60);
-            this.spatialFilterButtonPanel.TabIndex = 2;
-            // 
-            // btnRectangle
-            // 
-            this.btnRectangle.Location = new System.Drawing.Point(3, 3);
-            this.btnRectangle.Name = "btnRectangle";
-            this.btnRectangle.Size = new System.Drawing.Size(75, 23);
-            this.btnRectangle.TabIndex = 2;
-            this.btnRectangle.Text = "Rectangle";
-            this.btnRectangle.UseVisualStyleBackColor = true;
-            this.btnRectangle.Click += new System.EventHandler(this.btnRectangle_Click);
-            // 
-            // btnPolygon
-            // 
-            this.btnPolygon.Location = new System.Drawing.Point(84, 3);
-            this.btnPolygon.Name = "btnPolygon";
-            this.btnPolygon.Size = new System.Drawing.Size(75, 23);
-            this.btnPolygon.TabIndex = 3;
-            this.btnPolygon.Text = "Polygon";
-            this.btnPolygon.UseVisualStyleBackColor = true;
-            this.btnPolygon.Click += new System.EventHandler(this.btnPolygon_Click);
-            // 
-            // btnClear
-            // 
-            this.btnClear.Location = new System.Drawing.Point(3, 32);
-            this.btnClear.Name = "btnClear";
-            this.btnClear.Size = new System.Drawing.Size(75, 23);
-            this.btnClear.TabIndex = 4;
-            this.btnClear.Text = "Clear";
-            this.btnClear.UseVisualStyleBackColor = true;
-            this.btnClear.Click += new System.EventHandler(this.btnClear_Click);
-            // 
-            // chkSpatialFilter
-            // 
-            this.chkSpatialFilter.AutoSize = true;
-            this.chkSpatialFilter.Location = new System.Drawing.Point(19, 19);
-            this.chkSpatialFilter.Name = "chkSpatialFilter";
-            this.chkSpatialFilter.Size = new System.Drawing.Size(65, 17);
-            this.chkSpatialFilter.TabIndex = 1;
-            this.chkSpatialFilter.Text = "Enabled";
-            this.chkSpatialFilter.UseVisualStyleBackColor = true;
-            // 
-            // btnExecute
-            // 
-            this.btnExecute.Location = new System.Drawing.Point(16, 395);
-            this.btnExecute.Name = "btnExecute";
-            this.btnExecute.Size = new System.Drawing.Size(75, 23);
-            this.btnExecute.TabIndex = 3;
-            this.btnExecute.Text = "Execute";
-            this.btnExecute.UseVisualStyleBackColor = true;
-            this.btnExecute.Click += new System.EventHandler(this.btnExecute_Click);
-            // 
-            // label5
-            // 
-            this.label5.AutoSize = true;
-            this.label5.Location = new System.Drawing.Point(97, 400);
-            this.label5.Name = "label5";
-            this.label5.Size = new System.Drawing.Size(42, 13);
-            this.label5.TabIndex = 4;
-            this.label5.Text = "Results";
-            // 
-            // numResults
-            // 
-            this.numResults.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.numResults.Location = new System.Drawing.Point(143, 398);
-            this.numResults.Maximum = new decimal(new int[] {
-            10000,
-            0,
-            0,
-            0});
-            this.numResults.Name = "numResults";
-            this.numResults.Size = new System.Drawing.Size(104, 20);
-            this.numResults.TabIndex = 5;
-            this.numResults.Value = new decimal(new int[] {
-            100,
-            0,
-            0,
-            0});
-            // 
-            // MgQueryControl
-            // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.Controls.Add(this.numResults);
-            this.Controls.Add(this.label5);
-            this.Controls.Add(this.btnExecute);
-            this.Controls.Add(this.groupBox3);
-            this.Controls.Add(this.groupBox2);
-            this.Controls.Add(this.groupBox1);
-            this.Name = "MgQueryControl";
-            this.Size = new System.Drawing.Size(266, 431);
-            this.groupBox1.ResumeLayout(false);
-            this.groupBox1.PerformLayout();
-            this.groupBox2.ResumeLayout(false);
-            this.groupBox2.PerformLayout();
-            this.groupBox3.ResumeLayout(false);
-            this.groupBox3.PerformLayout();
-            this.spatialFilterButtonPanel.ResumeLayout(false);
-            ((System.ComponentModel.ISupportInitialize)(this.numResults)).EndInit();
-            this.ResumeLayout(false);
-            this.PerformLayout();
-
-        }
-
-        #endregion
-
-        private System.Windows.Forms.GroupBox groupBox1;
-        private System.Windows.Forms.Label label1;
-        private System.Windows.Forms.ComboBox cmbLayer;
-        private System.Windows.Forms.GroupBox groupBox2;
-        private System.Windows.Forms.CheckBox chkPropFilterEnabled;
-        private System.Windows.Forms.GroupBox groupBox3;
-        private System.Windows.Forms.CheckBox chkSpatialFilter;
-        private System.Windows.Forms.TextBox txtValue;
-        private System.Windows.Forms.Label label4;
-        private System.Windows.Forms.ComboBox cmbOperator;
-        private System.Windows.Forms.Label label3;
-        private System.Windows.Forms.ComboBox cmbProperty;
-        private System.Windows.Forms.Label label2;
-        private System.Windows.Forms.FlowLayoutPanel spatialFilterButtonPanel;
-        private System.Windows.Forms.Button btnRectangle;
-        private System.Windows.Forms.Button btnPolygon;
-        private System.Windows.Forms.Button btnClear;
-        private System.Windows.Forms.Button btnExecute;
-        private System.Windows.Forms.Label label5;
-        private System.Windows.Forms.NumericUpDown numResults;
-    }
-}

Modified: trunk/MgDev/Desktop/MapViewer/MgQueryControl.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgQueryControl.cs	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/MgQueryControl.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -1,204 +1,35 @@
 using System;
 using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.Data;
 using System.Text;
-using System.Windows.Forms;
+using System.ComponentModel;
 
 namespace OSGeo.MapGuide.Viewer
 {
-    public partial class MgQueryControl : UserControl
+    /// <summary>
+    /// A generic feature query component
+    /// </summary>
+    [ToolboxItem(true)]
+    public class MgQueryControl : MgViewerComponent
     {
-        private IMapViewer _viewer;
-        private MgWktReaderWriter _wktRw;
-        private MgGeometryFactory _geomFact;
-
-        private BindingList<MgDataPropertyDefinition> _properties;
-        private BindingList<MgLayerBase> _layers;
-
-        public MgQueryControl(IMapViewer viewer)
+        public MgQueryControl()
         {
-            InitializeComponent();
-            this.Disposed += new EventHandler(OnDisposed);
-            _viewer = viewer;
-            _properties = new BindingList<MgDataPropertyDefinition>();
-            _layers = new BindingList<MgLayerBase>();
-            _wktRw = new MgWktReaderWriter();
-            _geomFact = new MgGeometryFactory();
-
-            cmbOperator.DataSource = Enum.GetValues(typeof(QueryOperator));
-            cmbLayer.DataSource = _layers;
-            cmbProperty.DataSource = _properties;
-
-            cmbOperator.SelectedIndex = 0;
-            
-            var map = viewer.GetMap();
-            var layers = map.GetLayers();
-            for (var i = 0; i < layers.GetCount(); i++)
-            {
-                _layers.Add(layers.GetItem(i));
-            }
-            cmbLayer.SelectedIndex = 0;
+            this.Icon = Properties.Resources.search;
+            this.Label = Properties.Resources.TitleQuery;
         }
 
-        void OnDisposed(object sender, EventArgs e)
+        protected override MgControlImpl CreateControlImpl()
         {
-            _properties.Clear();
-            _layers.Clear();
-            _wktRw.Dispose();
-            _wktRw = null;
-            _geomFact.Dispose();
-            _geomFact = null;
+            return new MgQueryControlImpl(this.Viewer);
         }
 
-        private void cmbLayer_SelectedIndexChanged(object sender, EventArgs e)
+        protected override void SubscribeViewerEvents(IMapViewer viewer)
         {
-            var layer = cmbLayer.SelectedItem as MgLayerBase;
-            if (layer != null)
-            {
-                var cls = layer.GetClassDefinition();
-                var clsProps = cls.GetProperties();
-                _properties.Clear();
-                for (var i = 0; i < clsProps.GetCount(); i++)
-                {
-                    var prop = clsProps.GetItem(i);
-                    if (prop.GetPropertyType() == MgFeaturePropertyType.DataProperty)
-                    {
-                        _properties.Add((MgDataPropertyDefinition)prop);
-                    }
-                }
-                cmbProperty.SelectedIndex = 0;
-            }
+            base.SubscribeViewerEvents(viewer);
         }
 
-        static string MakeWktPolygon(double x1, double y1, double x2, double y2)
+        protected override void UnsubscribeViewerEvents(IMapViewer viewer)
         {
-            return "POLYGON((" + x1 + " " + y1 + ", " + x2 + " " + y1 + ", " + x2 + " " + y2 + ", " + x1 + " " + y2 + ", " + x1 + " " + y1 + "))";
+            base.UnsubscribeViewerEvents(viewer);
         }
-
-        private MgGeometry _filterGeometry;
-
-        private void btnRectangle_Click(object sender, EventArgs e)
-        {
-            _viewer.DigitizeRectangle((llx, lly, urx, ury) =>
-            {
-                ClearFilterGeometry();
-                _filterGeometry = _wktRw.Read(MakeWktPolygon(llx, lly, urx, ury));
-            });
-        }
-
-        private void btnPolygon_Click(object sender, EventArgs e)
-        {
-            _viewer.DigitizePolygon((coordinates) =>
-            {
-                ClearFilterGeometry();
-                MgCoordinateCollection coords = new MgCoordinateCollection();
-                for (int i = 0; i < coordinates.GetLength(0); i++)
-                {
-                    coords.Add(_geomFact.CreateCoordinateXY(coordinates[i, 0], coordinates[i, 1]));
-                }
-                coords.Add(_geomFact.CreateCoordinateXY(coordinates[0, 0], coordinates[0, 1]));
-                MgLinearRing ring = _geomFact.CreateLinearRing(coords);
-                _filterGeometry = _geomFact.CreatePolygon(ring, null);
-            });
-        }
-
-        private void ClearFilterGeometry()
-        {
-            if (_filterGeometry != null)
-                _filterGeometry.Dispose();
-        }
-
-        private void btnClear_Click(object sender, EventArgs e)
-        {
-            ClearFilterGeometry();
-        }
-
-        private void btnExecute_Click(object sender, EventArgs e)
-        {
-            var query = new MgFeatureQueryOptions();
-            var provider = _viewer.GetProvider();
-            var layer = (MgLayerBase)cmbLayer.SelectedItem;
-            var prop = (MgDataPropertyDefinition)cmbProperty.SelectedItem;
-            var op = (QueryOperator)cmbOperator.SelectedItem;
-
-            if (chkPropFilterEnabled.Checked)
-                query.SetFilter(FilterToString(prop, op, txtValue.Text));
-            if (chkSpatialFilter.Checked)
-                query.SetSpatialFilter(layer.GetFeatureGeometryName(), _filterGeometry, MgFeatureSpatialOperations.Intersects);
-
-            var reader = layer.SelectFeatures(query);
-            new MgQueryResultsDialog(_viewer, layer, reader, Convert.ToInt32(numResults.Value)).Show();
-        }
-
-        static string FilterToString(MgDataPropertyDefinition prop, QueryOperator op, string value)
-        {
-            var sb = new StringBuilder();
-
-            sb.Append(prop.Name + " ");
-
-            switch (op)
-            {
-                case QueryOperator.EqualTo:
-                    sb.Append(" = ");
-                    break;
-                case QueryOperator.GreaterThan:
-                    sb.Append(" > ");
-                    break;
-                case QueryOperator.GreaterThanOrEqualTo:
-                    sb.Append(" >= ");
-                    break;
-                case QueryOperator.In:
-                    sb.Append(" IN ");
-                    break;
-                case QueryOperator.LessThan:
-                    sb.Append(" < ");
-                    break;
-                case QueryOperator.LessThanOrEqualTo:
-                    sb.Append(" <= ");
-                    break;
-                case QueryOperator.Like:
-                    sb.Append(" LIKE ");
-                    break;
-                case QueryOperator.NotEqualTo:
-                    sb.Append(" <> ");
-                    break;
-            }
-
-            if (op == QueryOperator.In)
-            {
-                sb.Append("(");
-                sb.Append(value);
-                sb.Append(")");
-            }
-            else
-            {
-                if (prop.DataType == MgPropertyType.String)
-                {
-                    sb.Append("'");
-                    sb.Append(value);
-                    sb.Append("'");
-                }
-                else
-                {
-                    sb.Append(value);
-                }
-            }
-
-            return sb.ToString();
-        }
     }
-
-    public enum QueryOperator
-    {
-        EqualTo,
-        NotEqualTo,
-        GreaterThan,
-        GreaterThanOrEqualTo,
-        LessThan,
-        LessThanOrEqualTo,
-        Like,
-        In
-    }
 }

Deleted: trunk/MgDev/Desktop/MapViewer/MgQueryControl.resx
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgQueryControl.resx	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/MgQueryControl.resx	2012-05-03 14:38:06 UTC (rev 6609)
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-</root>
\ No newline at end of file

Copied: trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.Designer.cs (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgQueryControlImpl.Designer.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.Designer.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.Designer.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,329 @@
+namespace OSGeo.MapGuide.Viewer
+{
+    partial class MgQueryControlImpl
+    {
+        /// <summary> 
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.groupBox1 = new System.Windows.Forms.GroupBox();
+            this.label1 = new System.Windows.Forms.Label();
+            this.cmbLayer = new System.Windows.Forms.ComboBox();
+            this.groupBox2 = new System.Windows.Forms.GroupBox();
+            this.txtValue = new System.Windows.Forms.TextBox();
+            this.label4 = new System.Windows.Forms.Label();
+            this.cmbOperator = new System.Windows.Forms.ComboBox();
+            this.label3 = new System.Windows.Forms.Label();
+            this.cmbProperty = new System.Windows.Forms.ComboBox();
+            this.label2 = new System.Windows.Forms.Label();
+            this.chkPropFilterEnabled = new System.Windows.Forms.CheckBox();
+            this.groupBox3 = new System.Windows.Forms.GroupBox();
+            this.spatialFilterButtonPanel = new System.Windows.Forms.FlowLayoutPanel();
+            this.btnRectangle = new System.Windows.Forms.Button();
+            this.btnPolygon = new System.Windows.Forms.Button();
+            this.btnClear = new System.Windows.Forms.Button();
+            this.chkSpatialFilter = new System.Windows.Forms.CheckBox();
+            this.btnExecute = new System.Windows.Forms.Button();
+            this.label5 = new System.Windows.Forms.Label();
+            this.numResults = new System.Windows.Forms.NumericUpDown();
+            this.groupBox1.SuspendLayout();
+            this.groupBox2.SuspendLayout();
+            this.groupBox3.SuspendLayout();
+            this.spatialFilterButtonPanel.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numResults)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // groupBox1
+            // 
+            this.groupBox1.Controls.Add(this.label1);
+            this.groupBox1.Controls.Add(this.cmbLayer);
+            this.groupBox1.Dock = System.Windows.Forms.DockStyle.Top;
+            this.groupBox1.Location = new System.Drawing.Point(0, 0);
+            this.groupBox1.Name = "groupBox1";
+            this.groupBox1.Size = new System.Drawing.Size(266, 82);
+            this.groupBox1.TabIndex = 0;
+            this.groupBox1.TabStop = false;
+            this.groupBox1.Text = "Layer";
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(16, 20);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(75, 13);
+            this.label1.TabIndex = 1;
+            this.label1.Text = "Select a Layer";
+            // 
+            // cmbLayer
+            // 
+            this.cmbLayer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbLayer.DisplayMember = "Name";
+            this.cmbLayer.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbLayer.FormattingEnabled = true;
+            this.cmbLayer.Location = new System.Drawing.Point(16, 45);
+            this.cmbLayer.Name = "cmbLayer";
+            this.cmbLayer.Size = new System.Drawing.Size(231, 21);
+            this.cmbLayer.TabIndex = 0;
+            this.cmbLayer.SelectedIndexChanged += new System.EventHandler(this.cmbLayer_SelectedIndexChanged);
+            // 
+            // groupBox2
+            // 
+            this.groupBox2.Controls.Add(this.txtValue);
+            this.groupBox2.Controls.Add(this.label4);
+            this.groupBox2.Controls.Add(this.cmbOperator);
+            this.groupBox2.Controls.Add(this.label3);
+            this.groupBox2.Controls.Add(this.cmbProperty);
+            this.groupBox2.Controls.Add(this.label2);
+            this.groupBox2.Controls.Add(this.chkPropFilterEnabled);
+            this.groupBox2.Dock = System.Windows.Forms.DockStyle.Top;
+            this.groupBox2.Location = new System.Drawing.Point(0, 82);
+            this.groupBox2.Name = "groupBox2";
+            this.groupBox2.Size = new System.Drawing.Size(266, 187);
+            this.groupBox2.TabIndex = 1;
+            this.groupBox2.TabStop = false;
+            this.groupBox2.Text = "Property Filter";
+            // 
+            // txtValue
+            // 
+            this.txtValue.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtValue.Location = new System.Drawing.Point(16, 145);
+            this.txtValue.Name = "txtValue";
+            this.txtValue.Size = new System.Drawing.Size(231, 20);
+            this.txtValue.TabIndex = 6;
+            // 
+            // label4
+            // 
+            this.label4.AutoSize = true;
+            this.label4.Location = new System.Drawing.Point(16, 129);
+            this.label4.Name = "label4";
+            this.label4.Size = new System.Drawing.Size(34, 13);
+            this.label4.TabIndex = 5;
+            this.label4.Text = "Value";
+            // 
+            // cmbOperator
+            // 
+            this.cmbOperator.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbOperator.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbOperator.FormattingEnabled = true;
+            this.cmbOperator.Location = new System.Drawing.Point(16, 101);
+            this.cmbOperator.Name = "cmbOperator";
+            this.cmbOperator.Size = new System.Drawing.Size(231, 21);
+            this.cmbOperator.TabIndex = 4;
+            // 
+            // label3
+            // 
+            this.label3.AutoSize = true;
+            this.label3.Location = new System.Drawing.Point(16, 85);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(48, 13);
+            this.label3.TabIndex = 3;
+            this.label3.Text = "Operator";
+            // 
+            // cmbProperty
+            // 
+            this.cmbProperty.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbProperty.DisplayMember = "Name";
+            this.cmbProperty.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbProperty.FormattingEnabled = true;
+            this.cmbProperty.Location = new System.Drawing.Point(16, 60);
+            this.cmbProperty.Name = "cmbProperty";
+            this.cmbProperty.Size = new System.Drawing.Size(231, 21);
+            this.cmbProperty.TabIndex = 2;
+            // 
+            // label2
+            // 
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(16, 44);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(46, 13);
+            this.label2.TabIndex = 1;
+            this.label2.Text = "Property";
+            // 
+            // chkPropFilterEnabled
+            // 
+            this.chkPropFilterEnabled.AutoSize = true;
+            this.chkPropFilterEnabled.Location = new System.Drawing.Point(19, 20);
+            this.chkPropFilterEnabled.Name = "chkPropFilterEnabled";
+            this.chkPropFilterEnabled.Size = new System.Drawing.Size(65, 17);
+            this.chkPropFilterEnabled.TabIndex = 0;
+            this.chkPropFilterEnabled.Text = "Enabled";
+            this.chkPropFilterEnabled.UseVisualStyleBackColor = true;
+            // 
+            // groupBox3
+            // 
+            this.groupBox3.Controls.Add(this.spatialFilterButtonPanel);
+            this.groupBox3.Controls.Add(this.chkSpatialFilter);
+            this.groupBox3.Dock = System.Windows.Forms.DockStyle.Top;
+            this.groupBox3.Location = new System.Drawing.Point(0, 269);
+            this.groupBox3.Name = "groupBox3";
+            this.groupBox3.Size = new System.Drawing.Size(266, 119);
+            this.groupBox3.TabIndex = 2;
+            this.groupBox3.TabStop = false;
+            this.groupBox3.Text = "Spatial Filter";
+            // 
+            // spatialFilterButtonPanel
+            // 
+            this.spatialFilterButtonPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.spatialFilterButtonPanel.Controls.Add(this.btnRectangle);
+            this.spatialFilterButtonPanel.Controls.Add(this.btnPolygon);
+            this.spatialFilterButtonPanel.Controls.Add(this.btnClear);
+            this.spatialFilterButtonPanel.Location = new System.Drawing.Point(19, 43);
+            this.spatialFilterButtonPanel.Name = "spatialFilterButtonPanel";
+            this.spatialFilterButtonPanel.Size = new System.Drawing.Size(228, 60);
+            this.spatialFilterButtonPanel.TabIndex = 2;
+            // 
+            // btnRectangle
+            // 
+            this.btnRectangle.Location = new System.Drawing.Point(3, 3);
+            this.btnRectangle.Name = "btnRectangle";
+            this.btnRectangle.Size = new System.Drawing.Size(75, 23);
+            this.btnRectangle.TabIndex = 2;
+            this.btnRectangle.Text = "Rectangle";
+            this.btnRectangle.UseVisualStyleBackColor = true;
+            this.btnRectangle.Click += new System.EventHandler(this.btnRectangle_Click);
+            // 
+            // btnPolygon
+            // 
+            this.btnPolygon.Location = new System.Drawing.Point(84, 3);
+            this.btnPolygon.Name = "btnPolygon";
+            this.btnPolygon.Size = new System.Drawing.Size(75, 23);
+            this.btnPolygon.TabIndex = 3;
+            this.btnPolygon.Text = "Polygon";
+            this.btnPolygon.UseVisualStyleBackColor = true;
+            this.btnPolygon.Click += new System.EventHandler(this.btnPolygon_Click);
+            // 
+            // btnClear
+            // 
+            this.btnClear.Location = new System.Drawing.Point(3, 32);
+            this.btnClear.Name = "btnClear";
+            this.btnClear.Size = new System.Drawing.Size(75, 23);
+            this.btnClear.TabIndex = 4;
+            this.btnClear.Text = "Clear";
+            this.btnClear.UseVisualStyleBackColor = true;
+            this.btnClear.Click += new System.EventHandler(this.btnClear_Click);
+            // 
+            // chkSpatialFilter
+            // 
+            this.chkSpatialFilter.AutoSize = true;
+            this.chkSpatialFilter.Location = new System.Drawing.Point(19, 19);
+            this.chkSpatialFilter.Name = "chkSpatialFilter";
+            this.chkSpatialFilter.Size = new System.Drawing.Size(65, 17);
+            this.chkSpatialFilter.TabIndex = 1;
+            this.chkSpatialFilter.Text = "Enabled";
+            this.chkSpatialFilter.UseVisualStyleBackColor = true;
+            // 
+            // btnExecute
+            // 
+            this.btnExecute.Location = new System.Drawing.Point(16, 395);
+            this.btnExecute.Name = "btnExecute";
+            this.btnExecute.Size = new System.Drawing.Size(75, 23);
+            this.btnExecute.TabIndex = 3;
+            this.btnExecute.Text = "Execute";
+            this.btnExecute.UseVisualStyleBackColor = true;
+            this.btnExecute.Click += new System.EventHandler(this.btnExecute_Click);
+            // 
+            // label5
+            // 
+            this.label5.AutoSize = true;
+            this.label5.Location = new System.Drawing.Point(97, 400);
+            this.label5.Name = "label5";
+            this.label5.Size = new System.Drawing.Size(42, 13);
+            this.label5.TabIndex = 4;
+            this.label5.Text = "Results";
+            // 
+            // numResults
+            // 
+            this.numResults.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.numResults.Location = new System.Drawing.Point(143, 398);
+            this.numResults.Maximum = new decimal(new int[] {
+            10000,
+            0,
+            0,
+            0});
+            this.numResults.Name = "numResults";
+            this.numResults.Size = new System.Drawing.Size(104, 20);
+            this.numResults.TabIndex = 5;
+            this.numResults.Value = new decimal(new int[] {
+            100,
+            0,
+            0,
+            0});
+            // 
+            // MgQueryControl
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.numResults);
+            this.Controls.Add(this.label5);
+            this.Controls.Add(this.btnExecute);
+            this.Controls.Add(this.groupBox3);
+            this.Controls.Add(this.groupBox2);
+            this.Controls.Add(this.groupBox1);
+            this.Name = "MgQueryControl";
+            this.Size = new System.Drawing.Size(266, 431);
+            this.groupBox1.ResumeLayout(false);
+            this.groupBox1.PerformLayout();
+            this.groupBox2.ResumeLayout(false);
+            this.groupBox2.PerformLayout();
+            this.groupBox3.ResumeLayout(false);
+            this.groupBox3.PerformLayout();
+            this.spatialFilterButtonPanel.ResumeLayout(false);
+            ((System.ComponentModel.ISupportInitialize)(this.numResults)).EndInit();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.GroupBox groupBox1;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.ComboBox cmbLayer;
+        private System.Windows.Forms.GroupBox groupBox2;
+        private System.Windows.Forms.CheckBox chkPropFilterEnabled;
+        private System.Windows.Forms.GroupBox groupBox3;
+        private System.Windows.Forms.CheckBox chkSpatialFilter;
+        private System.Windows.Forms.TextBox txtValue;
+        private System.Windows.Forms.Label label4;
+        private System.Windows.Forms.ComboBox cmbOperator;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.ComboBox cmbProperty;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.FlowLayoutPanel spatialFilterButtonPanel;
+        private System.Windows.Forms.Button btnRectangle;
+        private System.Windows.Forms.Button btnPolygon;
+        private System.Windows.Forms.Button btnClear;
+        private System.Windows.Forms.Button btnExecute;
+        private System.Windows.Forms.Label label5;
+        private System.Windows.Forms.NumericUpDown numResults;
+    }
+}

Copied: trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.cs (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgQueryControlImpl.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,205 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+
+namespace OSGeo.MapGuide.Viewer
+{
+    internal partial class MgQueryControlImpl : MgControlImpl
+    {
+        private IMapViewer _viewer;
+        private MgWktReaderWriter _wktRw;
+        private MgGeometryFactory _geomFact;
+
+        private BindingList<MgDataPropertyDefinition> _properties;
+        private BindingList<MgLayerBase> _layers;
+
+        public MgQueryControlImpl(IMapViewer viewer)
+        {
+            InitializeComponent();
+            this.Title = Properties.Resources.TitleQuery;
+            this.Disposed += new EventHandler(OnDisposed);
+            _viewer = viewer;
+            _properties = new BindingList<MgDataPropertyDefinition>();
+            _layers = new BindingList<MgLayerBase>();
+            _wktRw = new MgWktReaderWriter();
+            _geomFact = new MgGeometryFactory();
+
+            cmbOperator.DataSource = Enum.GetValues(typeof(QueryOperator));
+            cmbLayer.DataSource = _layers;
+            cmbProperty.DataSource = _properties;
+
+            cmbOperator.SelectedIndex = 0;
+            
+            var map = viewer.GetMap();
+            var layers = map.GetLayers();
+            for (var i = 0; i < layers.GetCount(); i++)
+            {
+                _layers.Add(layers.GetItem(i));
+            }
+            cmbLayer.SelectedIndex = 0;
+        }
+
+        void OnDisposed(object sender, EventArgs e)
+        {
+            _properties.Clear();
+            _layers.Clear();
+            _wktRw.Dispose();
+            _wktRw = null;
+            _geomFact.Dispose();
+            _geomFact = null;
+        }
+
+        private void cmbLayer_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            var layer = cmbLayer.SelectedItem as MgLayerBase;
+            if (layer != null)
+            {
+                var cls = layer.GetClassDefinition();
+                var clsProps = cls.GetProperties();
+                _properties.Clear();
+                for (var i = 0; i < clsProps.GetCount(); i++)
+                {
+                    var prop = clsProps.GetItem(i);
+                    if (prop.GetPropertyType() == MgFeaturePropertyType.DataProperty)
+                    {
+                        _properties.Add((MgDataPropertyDefinition)prop);
+                    }
+                }
+                cmbProperty.SelectedIndex = 0;
+            }
+        }
+
+        static string MakeWktPolygon(double x1, double y1, double x2, double y2)
+        {
+            return "POLYGON((" + x1 + " " + y1 + ", " + x2 + " " + y1 + ", " + x2 + " " + y2 + ", " + x1 + " " + y2 + ", " + x1 + " " + y1 + "))";
+        }
+
+        private MgGeometry _filterGeometry;
+
+        private void btnRectangle_Click(object sender, EventArgs e)
+        {
+            _viewer.DigitizeRectangle((llx, lly, urx, ury) =>
+            {
+                ClearFilterGeometry();
+                _filterGeometry = _wktRw.Read(MakeWktPolygon(llx, lly, urx, ury));
+            });
+        }
+
+        private void btnPolygon_Click(object sender, EventArgs e)
+        {
+            _viewer.DigitizePolygon((coordinates) =>
+            {
+                ClearFilterGeometry();
+                MgCoordinateCollection coords = new MgCoordinateCollection();
+                for (int i = 0; i < coordinates.GetLength(0); i++)
+                {
+                    coords.Add(_geomFact.CreateCoordinateXY(coordinates[i, 0], coordinates[i, 1]));
+                }
+                coords.Add(_geomFact.CreateCoordinateXY(coordinates[0, 0], coordinates[0, 1]));
+                MgLinearRing ring = _geomFact.CreateLinearRing(coords);
+                _filterGeometry = _geomFact.CreatePolygon(ring, null);
+            });
+        }
+
+        private void ClearFilterGeometry()
+        {
+            if (_filterGeometry != null)
+                _filterGeometry.Dispose();
+        }
+
+        private void btnClear_Click(object sender, EventArgs e)
+        {
+            ClearFilterGeometry();
+        }
+
+        private void btnExecute_Click(object sender, EventArgs e)
+        {
+            var query = new MgFeatureQueryOptions();
+            var provider = _viewer.GetProvider();
+            var layer = (MgLayerBase)cmbLayer.SelectedItem;
+            var prop = (MgDataPropertyDefinition)cmbProperty.SelectedItem;
+            var op = (QueryOperator)cmbOperator.SelectedItem;
+
+            if (chkPropFilterEnabled.Checked)
+                query.SetFilter(FilterToString(prop, op, txtValue.Text));
+            if (chkSpatialFilter.Checked)
+                query.SetSpatialFilter(layer.GetFeatureGeometryName(), _filterGeometry, MgFeatureSpatialOperations.Intersects);
+
+            var reader = layer.SelectFeatures(query);
+            new MgQueryResultsDialog(_viewer, layer, reader, Convert.ToInt32(numResults.Value)).Show();
+        }
+
+        static string FilterToString(MgDataPropertyDefinition prop, QueryOperator op, string value)
+        {
+            var sb = new StringBuilder();
+
+            sb.Append(prop.Name + " ");
+
+            switch (op)
+            {
+                case QueryOperator.EqualTo:
+                    sb.Append(" = ");
+                    break;
+                case QueryOperator.GreaterThan:
+                    sb.Append(" > ");
+                    break;
+                case QueryOperator.GreaterThanOrEqualTo:
+                    sb.Append(" >= ");
+                    break;
+                case QueryOperator.In:
+                    sb.Append(" IN ");
+                    break;
+                case QueryOperator.LessThan:
+                    sb.Append(" < ");
+                    break;
+                case QueryOperator.LessThanOrEqualTo:
+                    sb.Append(" <= ");
+                    break;
+                case QueryOperator.Like:
+                    sb.Append(" LIKE ");
+                    break;
+                case QueryOperator.NotEqualTo:
+                    sb.Append(" <> ");
+                    break;
+            }
+
+            if (op == QueryOperator.In)
+            {
+                sb.Append("(");
+                sb.Append(value);
+                sb.Append(")");
+            }
+            else
+            {
+                if (prop.DataType == MgPropertyType.String)
+                {
+                    sb.Append("'");
+                    sb.Append(value);
+                    sb.Append("'");
+                }
+                else
+                {
+                    sb.Append(value);
+                }
+            }
+
+            return sb.ToString();
+        }
+    }
+
+    public enum QueryOperator
+    {
+        EqualTo,
+        NotEqualTo,
+        GreaterThan,
+        GreaterThanOrEqualTo,
+        LessThan,
+        LessThanOrEqualTo,
+        Like,
+        In
+    }
+}

Copied: trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.resx (from rev 6608, branches/2.4/MgDev/Desktop/MapViewer/MgQueryControlImpl.resx)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.resx	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgQueryControlImpl.resx	2012-05-03 14:38:06 UTC (rev 6609)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file

Modified: trunk/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -1,7 +1,7 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:4.0.30319.225
+//     Runtime Version:2.0.50727.5420
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.
@@ -19,7 +19,7 @@
     // class via a tool like ResGen or Visual Studio.
     // To add or remove a member, edit your .ResX file then rerun ResGen
     // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
     internal class Resources {
@@ -604,6 +604,33 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Buffer.
+        /// </summary>
+        internal static string TitleBuffer {
+            get {
+                return ResourceManager.GetString("TitleBuffer", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Measure.
+        /// </summary>
+        internal static string TitleMeasure {
+            get {
+                return ResourceManager.GetString("TitleMeasure", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Query.
+        /// </summary>
+        internal static string TitleQuery {
+            get {
+                return ResourceManager.GetString("TitleQuery", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Tooltips are enabled. Click to disable.
         /// </summary>
         internal static string TooltipDisableTooltips {

Modified: trunk/MgDev/Desktop/MapViewer/Properties/Resources.resx
===================================================================
--- trunk/MgDev/Desktop/MapViewer/Properties/Resources.resx	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewer/Properties/Resources.resx	2012-05-03 14:38:06 UTC (rev 6609)
@@ -112,15 +112,15 @@
     <value>2.0</value>
   </resheader>
   <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <data name="TextDigitizePolygon" xml:space="preserve">
     <value>Digitize Polygon</value>
   </data>
-  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   <data name="layer_shape_polyline" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\layer-shape-polyline.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
@@ -367,4 +367,13 @@
   <data name="AreaLayerDef" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\AreaLayerDef.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
   </data>
+  <data name="TitleBuffer" xml:space="preserve">
+    <value>Buffer</value>
+  </data>
+  <data name="TitleMeasure" xml:space="preserve">
+    <value>Measure</value>
+  </data>
+  <data name="TitleQuery" xml:space="preserve">
+    <value>Query</value>
+  </data>
 </root>
\ No newline at end of file

Modified: trunk/MgDev/Desktop/MapViewerTest/Form1.Designer.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewerTest/Form1.Designer.cs	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewerTest/Form1.Designer.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -43,9 +43,13 @@
             this.quitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.testToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.loadCompactMapViewerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.debugToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.showConnectionPoolStatusToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.purgePooledConnectionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.ctxViewer = new System.Windows.Forms.ContextMenuStrip(this.components);
+            this.refreshMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.initialViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.toolStrip1 = new System.Windows.Forms.ToolStrip();
             this.btnDigitizePoint = new System.Windows.Forms.ToolStripButton();
             this.btnDigitizeLine = new System.Windows.Forms.ToolStripButton();
@@ -56,10 +60,8 @@
             this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
             this.btnPlotToDwf = new System.Windows.Forms.ToolStripButton();
             this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
-            this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
-            this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
-            this.toolStripButton3 = new System.Windows.Forms.ToolStripButton();
             this.toolStripButton4 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
             this.splitContainer1 = new System.Windows.Forms.SplitContainer();
             this.splitContainer2 = new System.Windows.Forms.SplitContainer();
             this.legend = new OSGeo.MapGuide.Viewer.MgLegend();
@@ -69,13 +71,25 @@
             this.thisIsALayerContextMenuToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.propertyPane = new OSGeo.MapGuide.Viewer.MgPropertyPane();
             this.viewer = new OSGeo.MapGuide.Viewer.MgMapViewer();
-            this.ctxViewer = new System.Windows.Forms.ContextMenuStrip(this.components);
-            this.refreshMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.initialViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer();
             this.toolbar = new OSGeo.MapGuide.Viewer.MgDefaultToolbar();
+            this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
+            this.mgInvokeComponentButton1 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
+            this.mgBufferControl1 = new OSGeo.MapGuide.Viewer.MgBufferControl();
+            this.mgInvokeComponentButton2 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
+            this.mgMeasureControl1 = new OSGeo.MapGuide.Viewer.MgMeasureControl();
+            this.mgInvokeComponentButton3 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
+            this.mgQueryControl1 = new OSGeo.MapGuide.Viewer.MgQueryControl();
+            this.mgInvokeComponentMenuStripItem1 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem();
+            this.mgInvokeComponentMenuStripItem2 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem();
+            this.mgInvokeComponentMenuStripItem3 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem();
+            this.mgInvokeComponentMenuStripItem4 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem();
+            this.mgInvokeComponentMenuStripItem5 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem();
+            this.mgInvokeComponentMenuStripItem6 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem();
+            this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
             this.statusStrip1.SuspendLayout();
             this.menuStrip1.SuspendLayout();
+            this.ctxViewer.SuspendLayout();
             this.toolStrip1.SuspendLayout();
             this.splitContainer1.Panel1.SuspendLayout();
             this.splitContainer1.Panel2.SuspendLayout();
@@ -85,10 +99,10 @@
             this.splitContainer2.SuspendLayout();
             this.ctxGroup.SuspendLayout();
             this.ctxLayer.SuspendLayout();
-            this.ctxViewer.SuspendLayout();
             this.toolStripContainer1.ContentPanel.SuspendLayout();
             this.toolStripContainer1.TopToolStripPanel.SuspendLayout();
             this.toolStripContainer1.SuspendLayout();
+            this.toolbar.SuspendLayout();
             this.SuspendLayout();
             // 
             // statusStrip1
@@ -139,6 +153,7 @@
             this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.fileToolStripMenuItem,
             this.testToolStripMenuItem,
+            this.toolsToolStripMenuItem,
             this.debugToolStripMenuItem});
             this.menuStrip1.Location = new System.Drawing.Point(0, 0);
             this.menuStrip1.Name = "menuStrip1";
@@ -192,6 +207,16 @@
             this.loadCompactMapViewerToolStripMenuItem.Text = "Load Compact Map Viewer";
             this.loadCompactMapViewerToolStripMenuItem.Click += new System.EventHandler(this.loadCompactMapViewerToolStripMenuItem_Click);
             // 
+            // toolsToolStripMenuItem
+            // 
+            this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.mgInvokeComponentMenuStripItem1,
+            this.mgInvokeComponentMenuStripItem2,
+            this.mgInvokeComponentMenuStripItem3});
+            this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
+            this.toolsToolStripMenuItem.Size = new System.Drawing.Size(48, 20);
+            this.toolsToolStripMenuItem.Text = "Tools";
+            // 
             // debugToolStripMenuItem
             // 
             this.debugToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -215,6 +240,32 @@
             this.purgePooledConnectionsToolStripMenuItem.Text = "Purge Pooled Connections";
             this.purgePooledConnectionsToolStripMenuItem.Click += new System.EventHandler(this.purgePooledConnectionsToolStripMenuItem_Click);
             // 
+            // ctxViewer
+            // 
+            this.ctxViewer.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.refreshMapToolStripMenuItem,
+            this.initialViewToolStripMenuItem,
+            this.toolStripSeparator5,
+            this.mgInvokeComponentMenuStripItem4,
+            this.mgInvokeComponentMenuStripItem5,
+            this.mgInvokeComponentMenuStripItem6});
+            this.ctxViewer.Name = "ctxViewer";
+            this.ctxViewer.Size = new System.Drawing.Size(153, 142);
+            // 
+            // refreshMapToolStripMenuItem
+            // 
+            this.refreshMapToolStripMenuItem.Name = "refreshMapToolStripMenuItem";
+            this.refreshMapToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+            this.refreshMapToolStripMenuItem.Text = "Refresh Map";
+            this.refreshMapToolStripMenuItem.Click += new System.EventHandler(this.refreshMapToolStripMenuItem_Click);
+            // 
+            // initialViewToolStripMenuItem
+            // 
+            this.initialViewToolStripMenuItem.Name = "initialViewToolStripMenuItem";
+            this.initialViewToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+            this.initialViewToolStripMenuItem.Text = "Initial View";
+            this.initialViewToolStripMenuItem.Click += new System.EventHandler(this.initialViewToolStripMenuItem_Click);
+            // 
             // toolStrip1
             // 
             this.toolStrip1.Dock = System.Windows.Forms.DockStyle.None;
@@ -228,10 +279,8 @@
             this.toolStripSeparator1,
             this.btnPlotToDwf,
             this.toolStripSeparator2,
-            this.toolStripButton1,
-            this.toolStripButton2,
-            this.toolStripButton3,
-            this.toolStripButton4});
+            this.toolStripButton4,
+            this.toolStripSeparator3});
             this.toolStrip1.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow;
             this.toolStrip1.Location = new System.Drawing.Point(0, 25);
             this.toolStrip1.Name = "toolStrip1";
@@ -320,33 +369,6 @@
             this.toolStripSeparator2.Name = "toolStripSeparator2";
             this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
             // 
-            // toolStripButton1
-            // 
-            this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
-            this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.toolStripButton1.Name = "toolStripButton1";
-            this.toolStripButton1.Size = new System.Drawing.Size(72, 22);
-            this.toolStripButton1.Text = "Measure";
-            this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click);
-            // 
-            // toolStripButton2
-            // 
-            this.toolStripButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image")));
-            this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.toolStripButton2.Name = "toolStripButton2";
-            this.toolStripButton2.Size = new System.Drawing.Size(59, 22);
-            this.toolStripButton2.Text = "Buffer";
-            this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click);
-            // 
-            // toolStripButton3
-            // 
-            this.toolStripButton3.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton3.Image")));
-            this.toolStripButton3.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.toolStripButton3.Name = "toolStripButton3";
-            this.toolStripButton3.Size = new System.Drawing.Size(59, 22);
-            this.toolStripButton3.Text = "Query";
-            this.toolStripButton3.Click += new System.EventHandler(this.toolStripButton3_Click);
-            // 
             // toolStripButton4
             // 
             this.toolStripButton4.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton4.Image")));
@@ -357,6 +379,11 @@
             this.toolStripButton4.ToolTipText = "Profile current map view";
             this.toolStripButton4.Click += new System.EventHandler(this.toolStripButton4_Click);
             // 
+            // toolStripSeparator3
+            // 
+            this.toolStripSeparator3.Name = "toolStripSeparator3";
+            this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25);
+            // 
             // splitContainer1
             // 
             this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
@@ -455,28 +482,6 @@
             this.viewer.ZoomInFactor = 0.75;
             this.viewer.ZoomOutFactor = 1.35;
             // 
-            // ctxViewer
-            // 
-            this.ctxViewer.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.refreshMapToolStripMenuItem,
-            this.initialViewToolStripMenuItem});
-            this.ctxViewer.Name = "ctxViewer";
-            this.ctxViewer.Size = new System.Drawing.Size(141, 48);
-            // 
-            // refreshMapToolStripMenuItem
-            // 
-            this.refreshMapToolStripMenuItem.Name = "refreshMapToolStripMenuItem";
-            this.refreshMapToolStripMenuItem.Size = new System.Drawing.Size(140, 22);
-            this.refreshMapToolStripMenuItem.Text = "Refresh Map";
-            this.refreshMapToolStripMenuItem.Click += new System.EventHandler(this.refreshMapToolStripMenuItem_Click);
-            // 
-            // initialViewToolStripMenuItem
-            // 
-            this.initialViewToolStripMenuItem.Name = "initialViewToolStripMenuItem";
-            this.initialViewToolStripMenuItem.Size = new System.Drawing.Size(140, 22);
-            this.initialViewToolStripMenuItem.Text = "Initial View";
-            this.initialViewToolStripMenuItem.Click += new System.EventHandler(this.initialViewToolStripMenuItem_Click);
-            // 
             // toolStripContainer1
             // 
             // 
@@ -499,6 +504,11 @@
             // toolbar
             // 
             this.toolbar.Dock = System.Windows.Forms.DockStyle.None;
+            this.toolbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.toolStripSeparator4,
+            this.mgInvokeComponentButton1,
+            this.mgInvokeComponentButton2,
+            this.mgInvokeComponentButton3});
             this.toolbar.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow;
             this.toolbar.Location = new System.Drawing.Point(0, 0);
             this.toolbar.Name = "toolbar";
@@ -509,6 +519,115 @@
             this.toolbar.Viewer = null;
             this.toolbar.ZoomOutMode = OSGeo.MapGuide.Viewer.ZoomOutMode.AutoZoom;
             // 
+            // toolStripSeparator4
+            // 
+            this.toolStripSeparator4.Name = "toolStripSeparator4";
+            this.toolStripSeparator4.Size = new System.Drawing.Size(6, 25);
+            // 
+            // mgInvokeComponentButton1
+            // 
+            this.mgInvokeComponentButton1.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton1.Image")));
+            this.mgInvokeComponentButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.mgInvokeComponentButton1.Name = "mgInvokeComponentButton1";
+            this.mgInvokeComponentButton1.Size = new System.Drawing.Size(59, 22);
+            this.mgInvokeComponentButton1.TargetComponent = this.mgBufferControl1;
+            this.mgInvokeComponentButton1.Text = "Buffer";
+            // 
+            // mgBufferControl1
+            // 
+            this.mgBufferControl1.Icon = ((System.Drawing.Image)(resources.GetObject("mgBufferControl1.Icon")));
+            this.mgBufferControl1.Label = "Buffer";
+            this.mgBufferControl1.ParentContainer = null;
+            this.mgBufferControl1.ToolTipText = null;
+            this.mgBufferControl1.Viewer = this.viewer;
+            // 
+            // mgInvokeComponentButton2
+            // 
+            this.mgInvokeComponentButton2.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton2.Image")));
+            this.mgInvokeComponentButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.mgInvokeComponentButton2.Name = "mgInvokeComponentButton2";
+            this.mgInvokeComponentButton2.Size = new System.Drawing.Size(72, 22);
+            this.mgInvokeComponentButton2.TargetComponent = this.mgMeasureControl1;
+            this.mgInvokeComponentButton2.Text = "Measure";
+            // 
+            // mgMeasureControl1
+            // 
+            this.mgMeasureControl1.Icon = ((System.Drawing.Image)(resources.GetObject("mgMeasureControl1.Icon")));
+            this.mgMeasureControl1.Label = "Measure";
+            this.mgMeasureControl1.ParentContainer = null;
+            this.mgMeasureControl1.ToolTipText = null;
+            this.mgMeasureControl1.Viewer = this.viewer;
+            // 
+            // mgInvokeComponentButton3
+            // 
+            this.mgInvokeComponentButton3.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton3.Image")));
+            this.mgInvokeComponentButton3.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.mgInvokeComponentButton3.Name = "mgInvokeComponentButton3";
+            this.mgInvokeComponentButton3.Size = new System.Drawing.Size(59, 22);
+            this.mgInvokeComponentButton3.TargetComponent = this.mgQueryControl1;
+            this.mgInvokeComponentButton3.Text = "Query";
+            // 
+            // mgQueryControl1
+            // 
+            this.mgQueryControl1.Icon = ((System.Drawing.Image)(resources.GetObject("mgQueryControl1.Icon")));
+            this.mgQueryControl1.Label = "Query";
+            this.mgQueryControl1.ParentContainer = null;
+            this.mgQueryControl1.ToolTipText = null;
+            this.mgQueryControl1.Viewer = this.viewer;
+            // 
+            // mgInvokeComponentMenuStripItem1
+            // 
+            this.mgInvokeComponentMenuStripItem1.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuStripItem1.Image")));
+            this.mgInvokeComponentMenuStripItem1.Name = "mgInvokeComponentMenuStripItem1";
+            this.mgInvokeComponentMenuStripItem1.Size = new System.Drawing.Size(152, 22);
+            this.mgInvokeComponentMenuStripItem1.TargetComponent = this.mgBufferControl1;
+            this.mgInvokeComponentMenuStripItem1.Text = "Buffer";
+            // 
+            // mgInvokeComponentMenuStripItem2
+            // 
+            this.mgInvokeComponentMenuStripItem2.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuStripItem2.Image")));
+            this.mgInvokeComponentMenuStripItem2.Name = "mgInvokeComponentMenuStripItem2";
+            this.mgInvokeComponentMenuStripItem2.Size = new System.Drawing.Size(152, 22);
+            this.mgInvokeComponentMenuStripItem2.TargetComponent = this.mgMeasureControl1;
+            this.mgInvokeComponentMenuStripItem2.Text = "Measure";
+            // 
+            // mgInvokeComponentMenuStripItem3
+            // 
+            this.mgInvokeComponentMenuStripItem3.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuStripItem3.Image")));
+            this.mgInvokeComponentMenuStripItem3.Name = "mgInvokeComponentMenuStripItem3";
+            this.mgInvokeComponentMenuStripItem3.Size = new System.Drawing.Size(152, 22);
+            this.mgInvokeComponentMenuStripItem3.TargetComponent = this.mgQueryControl1;
+            this.mgInvokeComponentMenuStripItem3.Text = "Query";
+            // 
+            // mgInvokeComponentMenuStripItem4
+            // 
+            this.mgInvokeComponentMenuStripItem4.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuStripItem4.Image")));
+            this.mgInvokeComponentMenuStripItem4.Name = "mgInvokeComponentMenuStripItem4";
+            this.mgInvokeComponentMenuStripItem4.Size = new System.Drawing.Size(152, 22);
+            this.mgInvokeComponentMenuStripItem4.TargetComponent = this.mgBufferControl1;
+            this.mgInvokeComponentMenuStripItem4.Text = "Buffer";
+            // 
+            // mgInvokeComponentMenuStripItem5
+            // 
+            this.mgInvokeComponentMenuStripItem5.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuStripItem5.Image")));
+            this.mgInvokeComponentMenuStripItem5.Name = "mgInvokeComponentMenuStripItem5";
+            this.mgInvokeComponentMenuStripItem5.Size = new System.Drawing.Size(152, 22);
+            this.mgInvokeComponentMenuStripItem5.TargetComponent = this.mgMeasureControl1;
+            this.mgInvokeComponentMenuStripItem5.Text = "Measure";
+            // 
+            // mgInvokeComponentMenuStripItem6
+            // 
+            this.mgInvokeComponentMenuStripItem6.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuStripItem6.Image")));
+            this.mgInvokeComponentMenuStripItem6.Name = "mgInvokeComponentMenuStripItem6";
+            this.mgInvokeComponentMenuStripItem6.Size = new System.Drawing.Size(152, 22);
+            this.mgInvokeComponentMenuStripItem6.TargetComponent = this.mgQueryControl1;
+            this.mgInvokeComponentMenuStripItem6.Text = "Query";
+            // 
+            // toolStripSeparator5
+            // 
+            this.toolStripSeparator5.Name = "toolStripSeparator5";
+            this.toolStripSeparator5.Size = new System.Drawing.Size(149, 6);
+            // 
             // Form1
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -524,6 +643,7 @@
             this.statusStrip1.PerformLayout();
             this.menuStrip1.ResumeLayout(false);
             this.menuStrip1.PerformLayout();
+            this.ctxViewer.ResumeLayout(false);
             this.toolStrip1.ResumeLayout(false);
             this.toolStrip1.PerformLayout();
             this.splitContainer1.Panel1.ResumeLayout(false);
@@ -534,12 +654,13 @@
             this.splitContainer2.ResumeLayout(false);
             this.ctxGroup.ResumeLayout(false);
             this.ctxLayer.ResumeLayout(false);
-            this.ctxViewer.ResumeLayout(false);
             this.toolStripContainer1.ContentPanel.ResumeLayout(false);
             this.toolStripContainer1.TopToolStripPanel.ResumeLayout(false);
             this.toolStripContainer1.TopToolStripPanel.PerformLayout();
             this.toolStripContainer1.ResumeLayout(false);
             this.toolStripContainer1.PerformLayout();
+            this.toolbar.ResumeLayout(false);
+            this.toolbar.PerformLayout();
             this.ResumeLayout(false);
             this.PerformLayout();
 
@@ -586,11 +707,24 @@
         private System.Windows.Forms.ContextMenuStrip ctxViewer;
         private System.Windows.Forms.ToolStripMenuItem refreshMapToolStripMenuItem;
         private System.Windows.Forms.ToolStripMenuItem initialViewToolStripMenuItem;
-        private System.Windows.Forms.ToolStripButton toolStripButton1;
-        private System.Windows.Forms.ToolStripButton toolStripButton2;
-        private System.Windows.Forms.ToolStripButton toolStripButton3;
         private System.Windows.Forms.ToolStripButton toolStripButton4;
         private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
+        private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
+        private OSGeo.MapGuide.Viewer.MgBufferControl mgBufferControl1;
+        private OSGeo.MapGuide.Viewer.MgQueryControl mgQueryControl1;
+        private OSGeo.MapGuide.Viewer.MgMeasureControl mgMeasureControl1;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
+        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton1;
+        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton2;
+        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton3;
+        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem mgInvokeComponentMenuStripItem1;
+        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem mgInvokeComponentMenuStripItem2;
+        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem mgInvokeComponentMenuStripItem3;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
+        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem mgInvokeComponentMenuStripItem4;
+        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem mgInvokeComponentMenuStripItem5;
+        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuStripItem mgInvokeComponentMenuStripItem6;
     }
 }
 

Modified: trunk/MgDev/Desktop/MapViewerTest/Form1.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewerTest/Form1.cs	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewerTest/Form1.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -444,38 +444,6 @@
             viewer.InitialMapView();
         }
 
-        private void toolStripButton1_Click(object sender, EventArgs e)
-        {
-            var ctrl = new MgLineMeasureControl(viewer, MeasurementUnit.Kilometers);
-            var frm = new Form();
-            frm.Text = "Measure";
-            ctrl.Dock = DockStyle.Fill;
-            frm.Controls.Add(ctrl);
-            frm.Show();
-        }
-
-        private void toolStripButton2_Click(object sender, EventArgs e)
-        {
-            var ctrl = new MgBufferControl(viewer);
-            var frm = new Form();
-            frm.Text = "Buffer";
-            frm.Size = new System.Drawing.Size(250, 601);
-            ctrl.Dock = DockStyle.Fill;
-            frm.Controls.Add(ctrl);
-            frm.Show();
-        }
-
-        private void toolStripButton3_Click(object sender, EventArgs e)
-        {
-            var ctrl = new MgQueryControl(viewer);
-            var frm = new Form();
-            frm.Text = "Query";
-            frm.Size = new System.Drawing.Size(266, 460);
-            ctrl.Dock = DockStyle.Fill;
-            frm.Controls.Add(ctrl);
-            frm.Show();
-        }
-
         private void toolStripButton4_Click(object sender, EventArgs e)
         {
             var prof = (MgProfilingService)fact.CreateService(MgServiceType.ProfilingService);

Modified: trunk/MgDev/Desktop/MapViewerTest/Form1.resx
===================================================================
--- trunk/MgDev/Desktop/MapViewerTest/Form1.resx	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewerTest/Form1.resx	2012-05-03 14:38:06 UTC (rev 6609)
@@ -123,55 +123,127 @@
   <metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>133, 17</value>
   </metadata>
-  <metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>248, 17</value>
-  </metadata>
   <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
-  <data name="toolStripButton1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="mgInvokeComponentMenuStripItem1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
-        ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
-        HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
-        rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
-        TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
-        oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
-        7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
-        xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
-        LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
-        KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
+        tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
+        jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
+        T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
+        m+XGNsUKQli5ZJIMJC+xX3WUSWRl1tjD3qYvxcLhg+OZDKTP3OCKD275vCwePX55JhMwHkqFAA+vlnH8
+        /K2AGTPfUjm4xKhoOn1RwYyZbzs2b3Nq+wYl21WUGY+s/QEOPqTsVU0Bn7+6iK2HAAcEuesalrYKHsnF
+        m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="toolStripButton2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <metadata name="mgBufferControl1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>745, 17</value>
+  </metadata>
+  <data name="mgBufferControl1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
-        ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
-        HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
-        rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
-        TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
-        oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
-        7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
-        xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
-        LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
-        KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
+        tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
+        jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
+        T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
+        m+XGNsUKQli5ZJIMJC+xX3WUSWRl1tjD3qYvxcLhg+OZDKTP3OCKD275vCwePX55JhMwHkqFAA+vlnH8
+        /K2AGTPfUjm4xKhoOn1RwYyZbzs2b3Nq+wYl21WUGY+s/QEOPqTsVU0Bn7+6iK2HAAcEuesalrYKHsnF
+        m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="toolStripButton3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <metadata name="ctxViewer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>641, 17</value>
+  </metadata>
+  <data name="mgInvokeComponentMenuStripItem4.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
-        ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
-        HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
-        rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
-        TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
-        oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
-        7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
-        xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
-        LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
-        KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
+        tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
+        jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
+        T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
+        m+XGNsUKQli5ZJIMJC+xX3WUSWRl1tjD3qYvxcLhg+OZDKTP3OCKD275vCwePX55JhMwHkqFAA+vlnH8
+        /K2AGTPfUjm4xKhoOn1RwYyZbzs2b3Nq+wYl21WUGY+s/QEOPqTsVU0Bn7+6iK2HAAcEuesalrYKHsnF
+        m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
 </value>
   </data>
+  <data name="mgInvokeComponentMenuStripItem5.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
+        XEBRGJCjGUXPxCC2Vd1BbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
+        4kAccAMAcR22AO16RYIAAAAASUVORK5CYII=
+</value>
+  </data>
+  <metadata name="mgMeasureControl1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 56</value>
+  </metadata>
+  <data name="mgMeasureControl1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
+        XEBRGJCjGUXPxCC2Vd1BbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
+        4kAccAMAcR22AO16RYIAAAAASUVORK5CYII=
+</value>
+  </data>
+  <data name="mgInvokeComponentMenuStripItem6.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
+        YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
+        me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
+        ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
+        aDsYQqupDZSvgXRz/cLK6hqOzuOIiSIKioLrTAZC/AKH7OViLXu/oJt7UIWu4aVyEI0hnEwhm8tBYYAT
+        8QrBxCUCD7QXieI5M1hTwZPqpwhfJnF6da1eTkqyCoimxBKFLhKg7mgAOkaMsIPEjaRepkg+lFOQ+UL5
+        GgD3jhfWv/kgypm/yvt1FZSvAUxPz3qaDUbI2Sxk5n45kTepdBpNhlZQfkkr+/oG/J7JKci3t8gVCiWS
+        WFdGx8bBDzhhbn+t9eCexvO88Ir12efbgsS8yOfzLErY2NiEocWI3t5+2O12uN3uypDZ+XkPgepZa6k7
+        FGlN+/SyXq+H1WqFy+WqDHnsp7mHWCwWOJ2PfM6/QMxm8/9VQXCqhDQzM4ffTfzkLal2r4sAAAAASUVO
+        RK5CYII=
+</value>
+  </data>
+  <metadata name="mgQueryControl1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>894, 17</value>
+  </metadata>
+  <data name="mgQueryControl1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
+        YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
+        me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
+        ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
+        aDsYQqupDZSvgXRz/cLK6hqOzuOIiSIKioLrTAZC/AKH7OViLXu/oJt7UIWu4aVyEI0hnEwhm8tBYYAT
+        8QrBxCUCD7QXieI5M1hTwZPqpwhfJnF6da1eTkqyCoimxBKFLhKg7mgAOkaMsIPEjaRepkg+lFOQ+UL5
+        GgD3jhfWv/kgypm/yvt1FZSvAUxPz3qaDUbI2Sxk5n45kTepdBpNhlZQfkkr+/oG/J7JKci3t8gVCiWS
+        WFdGx8bBDzhhbn+t9eCexvO88Ir12efbgsS8yOfzLErY2NiEocWI3t5+2O12uN3uypDZ+XkPgepZa6k7
+        FGlN+/SyXq+H1WqFy+WqDHnsp7mHWCwWOJ2PfM6/QMxm8/9VQXCqhDQzM4ffTfzkLal2r4sAAAAASUVO
+        RK5CYII=
+</value>
+  </data>
+  <data name="mgInvokeComponentMenuStripItem2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
+        XEBRGJCjGUXPxCC2Vd1BbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
+        4kAccAMAcR22AO16RYIAAAAASUVORK5CYII=
+</value>
+  </data>
+  <data name="mgInvokeComponentMenuStripItem3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
+        YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
+        me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
+        ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
+        aDsYQqupDZSvgXRz/cLK6hqOzuOIiSIKioLrTAZC/AKH7OViLXu/oJt7UIWu4aVyEI0hnEwhm8tBYYAT
+        8QrBxCUCD7QXieI5M1hTwZPqpwhfJnF6da1eTkqyCoimxBKFLhKg7mgAOkaMsIPEjaRepkg+lFOQ+UL5
+        GgD3jhfWv/kgypm/yvt1FZSvAUxPz3qaDUbI2Sxk5n45kTepdBpNhlZQfkkr+/oG/J7JKci3t8gVCiWS
+        WFdGx8bBDzhhbn+t9eCexvO88Ir12efbgsS8yOfzLErY2NiEocWI3t5+2O12uN3uypDZ+XkPgepZa6k7
+        FGlN+/SyXq+H1WqFy+WqDHnsp7mHWCwWOJ2PfM6/QMxm8/9VQXCqhDQzM4ffTfzkLal2r4sAAAAASUVO
+        RK5CYII=
+</value>
+  </data>
+  <metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>248, 17</value>
+  </metadata>
   <data name="toolStripButton4.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
@@ -193,10 +265,42 @@
   <metadata name="ctxLayer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>545, 17</value>
   </metadata>
-  <metadata name="ctxViewer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>641, 17</value>
-  </metadata>
   <metadata name="toolbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>353, 17</value>
   </metadata>
+  <data name="mgInvokeComponentButton1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
+        tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
+        jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
+        T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
+        m+XGNsUKQli5ZJIMJC+xX3WUSWRl1tjD3qYvxcLhg+OZDKTP3OCKD275vCwePX55JhMwHkqFAA+vlnH8
+        /K2AGTPfUjm4xKhoOn1RwYyZbzs2b3Nq+wYl21WUGY+s/QEOPqTsVU0Bn7+6iK2HAAcEuesalrYKHsnF
+        m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
+</value>
+  </data>
+  <data name="mgInvokeComponentButton2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
+        XEBRGJCjGUXPxCC2Vd1BbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
+        4kAccAMAcR22AO16RYIAAAAASUVORK5CYII=
+</value>
+  </data>
+  <data name="mgInvokeComponentButton3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
+        YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
+        me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
+        ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
+        aDsYQqupDZSvgXRz/cLK6hqOzuOIiSIKioLrTAZC/AKH7OViLXu/oJt7UIWu4aVyEI0hnEwhm8tBYYAT
+        8QrBxCUCD7QXieI5M1hTwZPqpwhfJnF6da1eTkqyCoimxBKFLhKg7mgAOkaMsIPEjaRepkg+lFOQ+UL5
+        GgD3jhfWv/kgypm/yvt1FZSvAUxPz3qaDUbI2Sxk5n45kTepdBpNhlZQfkkr+/oG/J7JKci3t8gVCiWS
+        WFdGx8bBDzhhbn+t9eCexvO88Ir12efbgsS8yOfzLErY2NiEocWI3t5+2O12uN3uypDZ+XkPgepZa6k7
+        FGlN+/SyXq+H1WqFy+WqDHnsp7mHWCwWOJ2PfM6/QMxm8/9VQXCqhDQzM4ffTfzkLal2r4sAAAAASUVO
+        RK5CYII=
+</value>
+  </data>
 </root>
\ No newline at end of file

Modified: trunk/MgDev/Desktop/MapViewerTest/Program.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewerTest/Program.cs	2012-05-03 14:28:08 UTC (rev 6608)
+++ trunk/MgDev/Desktop/MapViewerTest/Program.cs	2012-05-03 14:38:06 UTC (rev 6609)
@@ -37,11 +37,15 @@
                 {
                     var resId = new MgResourceIdentifier(args[0]);
                     resId.Validate();
-
-                    frm.Load += (s, e) =>
+                    var fact = new MgServiceFactory();
+                    var resSvc = (MgResourceService)fact.CreateService(MgServiceType.ResourceService);
+                    if (resSvc.ResourceExists(resId))
                     {
-                        frm.LoadMap(resId);
-                    };
+                        frm.Load += (s, e) =>
+                        {
+                            frm.LoadMap(resId);
+                        };
+                    }
                 }
                 catch (MgException ex)
                 {



More information about the mapguide-commits mailing list