Skip to content

Add SketchWidget as Custom Editor Pro sample#21

Merged
TimPurdum merged 3 commits into
mainfrom
add-sketch-as-editor-sample
May 22, 2026
Merged

Add SketchWidget as Custom Editor Pro sample#21
TimPurdum merged 3 commits into
mainfrom
add-sketch-as-editor-sample

Conversation

@TimPurdum
Copy link
Copy Markdown
Contributor

Summary

  • New Pro sample (/sketch-as-editor) demonstrating how to drive the SketchWidget programmatically from C# while presenting a fully custom UI (Move/Save/Cancel buttons) and keeping the widget's built-in toolbar hidden.
  • A Move button arms an OnMapClick handler that hit-tests a target FeatureLayer, stages the picked Graphic into a companion GraphicsLayer, and hands it to SketchWidget.Update configured for SketchTool.Move. Save calls Complete()FeatureLayer.ApplyEdits; Cancel/Esc calls Cancel() and skips ApplyEdits via the Aborted flag on SketchUpdateEvent.
  • Adds a nav entry under the Interaction category with a new sketchEditor.svg icon, plus a small page-scoped stylesheet for the editor toolbar.

Test plan

  • Build samples/pro/dymaptic.GeoBlazor.Pro.Sample.Shared cleanly.
  • Run a Pro sample host (e.g. dymaptic.GeoBlazor.Pro.Sample.Wasm or .WebApp) and navigate to PRO: Sketch as Editor.
  • Verify Move arms the editor; clicking the polygon stages it; dragging works; Save commits via ApplyEdits and the layer refreshes with the new geometry.
  • Verify Cancel and Esc both abandon the edit without persisting and clean up the staging graphic.
  • Verify clicking off the polygon while armed reports "No feature at that point" and disarms cleanly.

🤖 Generated with Claude Code

Demonstrates driving the SketchWidget programmatically from C# while
presenting a fully custom UI: a Move button arms an OnMapClick handler
that hit-tests a target FeatureLayer, stages the picked Graphic into a
companion GraphicsLayer, and hands it to SketchWidget.Update with a
SketchToolUpdateOptions configured for SketchTool.Move. A Save button
calls Complete() to finalize the edit (forwarded through
FeatureLayer.ApplyEdits); a Cancel button (or the Esc key) calls
Cancel() and skips ApplyEdits.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new GeoBlazor Pro sample page (/sketch-as-editor) that uses SketchWidget.Update(SketchTool.Move) to implement a custom “Move / Save / Cancel” editing workflow with the built-in Sketch toolbar kept out of view, plus navigation and styling updates to surface the sample in the Pro menu.

Changes:

  • Introduces the new SketchAsEditor sample page and its scoped CSS for a custom editor toolbar/status UI.
  • Adds a Pro navigation entry pointing to the new sample, using a new sketchEditor.svg icon.
  • Updates Pro shared _Imports.razor to include dymaptic.GeoBlazor.Pro.Options (needed for SketchToolUpdateOptions).

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
samples/pro/dymaptic.GeoBlazor.Pro.Sample.Shared/Shared/ProNavMenu.cs Adds a new nav link for the “PRO: Sketch as Editor” sample using the new SVG icon.
samples/pro/dymaptic.GeoBlazor.Pro.Sample.Shared/Pages/SketchAsEditor.razor New sample page implementing the custom Sketch-driven move editor workflow and page metadata/description.
samples/pro/dymaptic.GeoBlazor.Pro.Sample.Shared/Pages/SketchAsEditor.razor.css Scoped styling for the custom editor toolbar and status pill.
samples/pro/dymaptic.GeoBlazor.Pro.Sample.Shared/_Imports.razor Imports dymaptic.GeoBlazor.Pro.Options so the sample can reference SketchToolUpdateOptions.
samples/core/dymaptic.GeoBlazor.Core.Sample.Shared/wwwroot/images/sketchEditor.svg Adds the SVG icon used by the new Pro nav entry (served from Core Sample Shared static assets).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +95 to +121
private async Task OnMapClick(ClickEvent evt)
{
if (!_moveArmed || _mapView is null || _featureLayer is null || _sketchWidget is null)
{
return;
}

// One-shot: disarm immediately so a missed click doesn't stay sticky.
_moveArmed = false;

HitTestOptions options = new()
{
IncludeByGeoBlazorId = [_featureLayer.Id]
};
HitTestResult hit = await _mapView.HitTest(evt, options);
Graphic? graphic = hit.Results.OfType<GraphicHit>().FirstOrDefault()?.Graphic;

if (graphic is null)
{
_statusMessage = "No feature at that point.";
return;
}

// Stage the picked graphic into the Sketch's own GraphicsLayer so the widget can operate on it.
await _sketchLayer!.Add(graphic);
await _sketchWidget.Update([graphic], _updateOptions);
_editing = true;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 30fe1e4 — added _sketchLayer is null to the early-return guard in OnMapClick and removed the null-forgiving ! operator from the subsequent _sketchLayer.Add(graphic) call.

Comment on lines +160 to +169
_editing = false;
Graphic? moved = evt.Graphics?.FirstOrDefault();

// Cancel() fires Complete with Aborted=true; skip ApplyEdits but still clean up the staging graphic.
if (evt.Aborted == true)
{
if (moved is not null)
{
await _sketchLayer!.Remove(moved);
}
Comment on lines +83 to +87
"SketchUpdateEvent is forwarded to FeatureLayer.ApplyEdits to persist the new geometry on the feature " +
"service, then the staging graphic is removed and the feature layer is refreshed so it redraws at the " +
"updated location. A Cancel button (and the Esc key) route through OnKeyDown to SketchWidget.Cancel(), " +
"which fires a Complete event with Aborted=true so ApplyEdits is skipped. The pattern is useful any time " +
"you need SketchViewModel's interactive move semantics inside a custom workflow with your own editor UI.";
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix this, but add text that points out it would also work with a hosted FeatureService.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in commit 5cd3f62. The description now says ApplyEdits targets the client-side in-memory source layer, and adds a sentence noting that the same call works equally well against a hosted FeatureService — just replace Source with a Url.

@TimPurdum TimPurdum merged commit b7ae24c into main May 22, 2026
@TimPurdum TimPurdum deleted the add-sketch-as-editor-sample branch May 22, 2026 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants