Class SfDiagram
Keeps Connectors in sync with the JavaScript-side diagram. See the remarks on
SfDiagram's Nodes counterpart (SfDiagram.Nodes.cs) for the general approach.
Implements
Inherited Members
Namespace: Syncfusion.Maui.Diagram
Assembly: Syncfusion.Maui.Diagram.dll
Syntax
public class SfDiagram : SfView, IDrawableLayout, IDrawable, IAbsoluteLayout, ILayout, IView, IElement, ITransform, IContainer, IList<IView>, ICollection<IView>, IEnumerable<IView>, IEnumerable, ISafeAreaView, IPadding, ICrossPlatformLayout, IVisualTreeElement, ISemanticsProvider, IDisposable
Remarks
Architecturally a sibling of Syncfusion.Maui.RichTextEditor.SfRichTextEditor: a WebView adapter
(Syncfusion.Maui.Diagram.IWebDiagramView), a JavaScript bridge (Syncfusion.Maui.Diagram.JavascriptBridge) reached through a
manager facade (Syncfusion.Maui.Diagram.DiagramManager), and model objects that mirror the underlying JavaScript
library's JSON schema. Phase 2 adds two-way interaction sync (drag/resize/rotate and selection flow
back from JavaScript into Node/Connector), Ports, and
AutoLayout-driven automatic arrangement. Data-bound generation, and connector endpoint
(as opposed to whole-node) drag sync, remain out of scope.
Symbol palette. A SymbolPalette placed as this control's own
layout sibling (e.g. both as Grid.Column children of the same Microsoft.Maui.Controls.Grid) is discovered
automatically — no SfDiagram.SymbolPalette/SymbolPalette.Diagram reference property either
way — the moment this control's own hosted WebView finishes loading (see Syncfusion.Maui.Diagram.SfDiagram.OnWebViewLoaded(System.Object,System.EventArgs)).
Its current configuration is folded straight into the shared page's own ej.diagrams.SymbolPalette
instance, rendered inside the very same document as this diagram's own ej.diagrams.Diagram
instance (see Resources/Raw/wwwroot/index.html), so EJ2's own built-in same-document
drag-and-drop moves a symbol from the palette onto the diagram with no custom C#/JS protocol at all.
See SymbolPalette's own remarks for why this replaced an earlier,
fully independent HybridWebView-per-control design.
Constructors
SfDiagram()
Initializes a new instance of the SfDiagram class.
Declaration
public SfDiagram()
Fields
AutoLayoutProperty
Identifies the AutoLayout bindable property.
Declaration
public static readonly BindableProperty AutoLayoutProperty
Field Value
| Type |
|---|
| Microsoft.Maui.Controls.BindableProperty |
ConnectorsProperty
Identifies the Connectors bindable property.
Declaration
public static readonly BindableProperty ConnectorsProperty
Field Value
| Type |
|---|
| Microsoft.Maui.Controls.BindableProperty |
IdProperty
Identifies the Id bindable property.
Declaration
public static readonly BindableProperty IdProperty
Field Value
| Type |
|---|
| Microsoft.Maui.Controls.BindableProperty |
NodesProperty
Identifies the Nodes bindable property.
Declaration
public static readonly BindableProperty NodesProperty
Field Value
| Type |
|---|
| Microsoft.Maui.Controls.BindableProperty |
Properties
AutoLayout
Gets or sets the automatic-arrangement configuration applied to Nodes/Connectors. Defaults to a DiagramLayout with None (manual positioning). Mutating this instance's properties in place — or assigning a new DiagramLayout — re-runs the layout once the diagram is ready.
Declaration
public DiagramLayout AutoLayout { get; set; }
Property Value
| Type |
|---|
| DiagramLayout |
Remarks
Named AutoLayout rather than Layout: Microsoft.Maui.Controls.VisualElement (by way of
IView) already declares a Layout(Rect bounds) method used to arrange the element, and
a property named "Layout" would hide it (CS0108) — the same shadowing mistake already avoided for
Width/Height/BackgroundColor elsewhere in this class.
Connectors
Gets or sets the diagram's connectors.
Declaration
public ObservableCollection<Connector> Connectors { get; set; }
Property Value
| Type |
|---|
| System.Collections.ObjectModel.ObservableCollection<Connector> |
Id
Gets or sets the diagram's identifier. Assigned automatically when left null.
Declaration
public string Id { get; set; }
Property Value
| Type |
|---|
| System.String |
Nodes
Gets or sets the diagram's nodes.
Declaration
public ObservableCollection<Node> Nodes { get; set; }
Property Value
| Type |
|---|
| System.Collections.ObjectModel.ObservableCollection<Node> |
Methods
Add(Connector)
Connector counterpart of Add(Node). Adds connector to the EJ2
canvas only, leaving Connectors untouched.
Declaration
public Task Add(Connector connector)
Parameters
| Type | Name | Description |
|---|---|---|
| Connector | connector |
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
Add(Node)
Adds node to the EJ2 canvas without putting it in Nodes.
Distinct from Nodes.Add: this method only mutates the EJ2 canvas
(the "remote" side) and does NOT make node part of the diagram's authoritative
model. Use this for cases where the application is rendering nodes it does not own in the managed
Nodes collection. To round-trip a node across both sides, use the standard
Nodes.Add(node) instead.
Declaration
public Task Add(Node node)
Parameters
| Type | Name | Description |
|---|---|---|
| Node | node |
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
CanRedoAsync()
Gets whether a redo is currently available. Always false before DiagramReady fires.
Declaration
public Task<bool> CanRedoAsync()
Returns
| Type |
|---|
| System.Threading.Tasks.Task<System.Boolean> |
CanUndoAsync()
Gets whether an undo is currently available. Always false before DiagramReady fires.
Declaration
public Task<bool> CanUndoAsync()
Returns
| Type |
|---|
| System.Threading.Tasks.Task<System.Boolean> |
Copy()
Copies the diagram's current selection to the diagram's clipboard and returns the clipboard
contents as a JSON string (a { nodes, connectors } bag in EJ2's wire shape). Returns
null when called before DiagramReady has fired, or when EJ2's
own copy returns an empty result.
Declaration
public Task<string> Copy()
Returns
| Type |
|---|
| System.Threading.Tasks.Task<System.String> |
Cut()
Cuts the diagram's current selection to the diagram's clipboard. Operates on whatever node and connector set is currently selected in the diagram's UI — typically selected by Syncfusion.Maui.Diagram.SfDiagram.SelectAll first, or by an earlier Selection-{node|connector}.id set in code. A no-op until DiagramReady has fired.
Declaration
public Task Cut()
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
Dispose()
Declaration
public void Dispose()
Dispose(Boolean)
Releases the diagram's WebView, JavaScript bridge, and event subscriptions.
Declaration
protected virtual void Dispose(bool disposing)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Boolean | disposing |
ExportDiagram(DiagramExportOptions)
Exports the diagram and returns the result as a string: a data URI
("data:image/png;base64,...", etc.) for Png/
Jpg/Bmp, or raw
<svg> markup for Svg. Returns
null if called before DiagramReady fires. This control never
writes the result to disk itself — decoding/saving/sharing it is left to the caller.
Declaration
public Task<string> ExportDiagram(DiagramExportOptions options = null)
Parameters
| Type | Name | Description |
|---|---|---|
| DiagramExportOptions | options | Export settings, or null (the default) to use every EJ2 default: PNG, Content, 25-unit margins on every side. |
Returns
| Type |
|---|
| System.Threading.Tasks.Task<System.String> |
FitToPage()
Zooms/pans so that every node and connector fits within the viewport. A no-op until DiagramReady has fired.
Declaration
public Task FitToPage()
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
LoadDiagram(String)
Replaces Nodes and Connectors with the diagram reconstructed from
json (as produced by Syncfusion.Maui.Diagram.SfDiagram.GetDiagramState(System.Boolean)). Whatever is currently
in Nodes/Connectors is cleared first — this replaces the diagram, it
doesn't merge into it. Works whether or not DiagramReady has fired yet, the same way
populating Nodes/Connectors directly does.
Declaration
public void LoadDiagram(string json)
Parameters
| Type | Name | Description |
|---|---|---|
| System.String | json |
Exceptions
| Type | Condition |
|---|---|
| System.Text.Json.JsonException | See Deserialize(String) for exactly what does and doesn't throw. |
Pan(Double, Double, Nullable<Point>)
Sets the diagram viewport's horizontal/vertical scroll offsets in diagram units.
focusedPoint, when non-null, sets the viewport's centre after the pan.
Declaration
public Task Pan(double horizontalOffset, double verticalOffset, Nullable<Point> focusedPoint = null)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Double | horizontalOffset | |
| System.Double | verticalOffset | |
| System.Nullable<Microsoft.Maui.Graphics.Point> | focusedPoint |
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
Paste(IEnumerable<DiagramElement>)
Pastes from the diagram's clipboard onto the diagram. Pass elements to paste
an explicit batch of nodes/connectors from your own collection; pass null (the
default) to paste whatever the diagram's current clipboard holds (the contents most recently
produced by Cut() or Copy()).
Declaration
public Task Paste(IEnumerable<DiagramElement> elements = null)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Collections.Generic.IEnumerable<DiagramElement> | elements |
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
Print(DiagramExportOptions)
Prints the diagram. A no-op until DiagramReady has fired.
Declaration
public Task Print(DiagramExportOptions options = null)
Parameters
| Type | Name | Description |
|---|---|---|
| DiagramExportOptions | options | Export settings applied before printing, or null (the default) to use every EJ2 default. |
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
Remarks
This calls straight through to EJ2's own print(), which opens a browser-style window and
calls its window.print() — not a native print flow. It is most likely to produce a real
print dialog on Windows (WebView2); iOS/Android's embedded WebViews commonly block or ignore
window.open/window.print() altogether. See the remarks on
Syncfusion.Maui.Diagram.DiagramManager.PrintAsync(Syncfusion.Maui.Diagram.DiagramExportOptions) for the full explanation (verified
directly against ej2.min.js). For a reliable cross-platform print experience, prefer
exporting an image with ExportDiagram(DiagramExportOptions) and printing it
through MAUI's own platform print/share APIs instead.
Redo()
Redoes the last undone action. A no-op until DiagramReady has fired or if there is
nothing to redo. Ctrl+Y/Ctrl+Shift+Z also trigger this from within the diagram's own
UI once it has focus; see the remarks on Undo().
Declaration
public Task Redo()
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
Remove(Connector)
Connector counterpart of Remove(Node). Removes connector from the
EJ2 canvas only, leaving Connectors untouched.
Declaration
public Task Remove(Connector connector)
Parameters
| Type | Name | Description |
|---|---|---|
| Connector | connector |
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
Remove(Node)
Removes node from the EJ2 canvas. Distinct from
Nodes.Remove: this method only mutates the EJ2 canvas and does
NOT remove node from Nodes.
Declaration
public Task Remove(Node node)
Parameters
| Type | Name | Description |
|---|---|---|
| Node | node |
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
SaveDiagram()
Serializes this diagram control to a JSON string — the same shape Syncfusion.Maui.Diagram.SfDiagram.GetDiagramState(System.Boolean) produces, the same string LoadDiagram(String) can later round-trip back into this control.
Declaration
public string SaveDiagram()
Returns
| Type | Description |
|---|---|
| System.String | A JSON string capturing Nodes and Connectors — including their annotations, ports, styles, and decorators — that LoadDiagram(String) (or Deserialize(String) directly) can later turn back into an equivalent diagram. Works whether or not DiagramReady has fired yet. |
Remarks
Provided as the natural-language counterpart to LoadDiagram(String) ("save the
diagram" → SaveDiagram, "load the diagram" → LoadDiagram) and as a synonym for
Syncfusion.Maui.Diagram.SfDiagram.GetDiagramState(System.Boolean) for callers who think in those terms. The output is the
native-side lossless DiagramStateSerializer JSON, not the EJ2 wire format and not the
image/SVG format ExportDiagram(DiagramExportOptions) returns — see
Syncfusion.Maui.Diagram.SfDiagram.GetDiagramState(System.Boolean)'s remarks for why those three are intentionally different.
This method does not write to disk, share, or persist the string anywhere — whatever the caller
does with the returned value (file, database, cloud, clipboard, network request) is entirely up to
them.
Undo()
Undoes the last undoable action (adding/removing/moving/resizing a Node or
Connector, etc.). A no-op until DiagramReady has fired or if there is
nothing to undo. Backed by the EJ2 UndoRedo module, which this control injects
automatically — no separate opt-in is required. Ctrl+Z also triggers this from within the
diagram's own UI once it has focus, since EJ2 wires that shortcut up itself once the module is injected.
Declaration
public Task Undo()
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
Zoom(Double, Nullable<Point>)
Multiplies the current zoom level by factor (e.g. 1.25 for "zoom in 25%",
0.8 for "zoom out 20%"). Pass focusedPoint to zoom centered on a
specific viewport point rather than the diagram's geometric centre.
Declaration
public Task Zoom(double factor, Nullable<Point> focusedPoint = null)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Double | factor | |
| System.Nullable<Microsoft.Maui.Graphics.Point> | focusedPoint |
Returns
| Type |
|---|
| System.Threading.Tasks.Task |
Events
CollectionChanged
Raised whenever a Node or Connector is added to, or removed from, this diagram — whether that happened because application code changed Nodes/Connectors directly, or because of something the user did in the WebView (a SymbolPalette drop, an interactively-drawn connector, a delete/cut, or an undo/redo of any of those — see DiagramCollectionChangedEventArgs's remarks). One event, either collection, any cause.
Declaration
public event EventHandler<DiagramCollectionChangedEventArgs> CollectionChanged
Event Type
| Type |
|---|
| System.EventHandler<DiagramCollectionChangedEventArgs> |
ConnectionChanged
Raised after a Connector's source and/or target endpoint finishes attaching to,
detaching from, or being re-routed between nodes/ports in the WebView. Fires once per
EJ2-side connectionChange "Changed" state with both pre/post values on the
DiagramConnectorConnectionChangedEventArgs.
Declaration
public event EventHandler<DiagramConnectorConnectionChangedEventArgs> ConnectionChanged
Event Type
| Type |
|---|
| System.EventHandler<DiagramConnectorConnectionChangedEventArgs> |
DiagramReady
Raised once the JavaScript-side ej.diagrams.Diagram instance has been created and is ready
to receive nodes and connectors. Nodes/connectors added to Nodes/Connectors
before this fires are not lost — they're included in the startup snapshot — so waiting for this
event is optional, not required, before populating the diagram.
Declaration
public event EventHandler DiagramReady
Event Type
| Type |
|---|
| System.EventHandler |
JavaScriptError
Raised when a call into the hosted page's JavaScript throws instead of completing normally — for
example, an environment problem like ej2.min.js failing to load, or a malformed payload.
Without a subscriber this is still visible via System.Diagnostics.Debug.WriteLine(System.String),
but a failure here is otherwise the reason the diagram silently doesn't render, so production apps
should consider handling it (e.g. logging it through their own diagnostics).
Declaration
public event EventHandler<DiagramJavaScriptErrorEventArgs> JavaScriptError
Event Type
| Type |
|---|
| System.EventHandler<DiagramJavaScriptErrorEventArgs> |
PositionChanged
Raised after a node finishes being dragged to a new position in the WebView. See DiagramNodePositionChangedEventArgs's remarks for exactly when this fires versus SizeChanged/RotationChanged.
Declaration
public event EventHandler<DiagramNodePositionChangedEventArgs> PositionChanged
Event Type
| Type |
|---|
| System.EventHandler<DiagramNodePositionChangedEventArgs> |
RotationChanged
Raised after a node finishes being rotated in the WebView.
Declaration
public event EventHandler<DiagramNodeRotationChangedEventArgs> RotationChanged
Event Type
| Type |
|---|
| System.EventHandler<DiagramNodeRotationChangedEventArgs> |
SelectionChanged
Raised after the user finishes selecting/deselecting nodes or connectors in the diagram's UI (Phase 2's two-way interaction sync).
Declaration
public event EventHandler<DiagramSelectionChangedEventArgs> SelectionChanged
Event Type
| Type |
|---|
| System.EventHandler<DiagramSelectionChangedEventArgs> |
SizeChanged
Raised after a node finishes being resized in the WebView. Deliberately hides
Microsoft.Maui.Controls.VisualElement.SizeChanged — the base control-layout-resize event every
Microsoft.Maui.Controls.VisualElement already has — with the langword_csharp_new
keyword below, since the name was requested for this node-level event specifically. Existing code
that wants the base control's own arranged-size event still can, by subscribing through a
Microsoft.Maui.Controls.VisualElement-typed reference (e.g. ((VisualElement)diagram).SizeChanged += ...)
instead of a SfDiagram-typed one.
Declaration
public event EventHandler<DiagramNodeSizeChangedEventArgs> SizeChanged
Event Type
| Type |
|---|
| System.EventHandler<DiagramNodeSizeChangedEventArgs> |
SourcePointChanged
Raised after a Connector's floating source endpoint finishes being dragged in the WebView. Fires once per drag-completion, with both pre-drag and post-drag positions on the DiagramConnectorSourcePointChangedEventArgs. Not raised for a source endpoint that was (or became) attached to a node/port — those instead raise ConnectionChanged.
Declaration
public event EventHandler<DiagramConnectorSourcePointChangedEventArgs> SourcePointChanged
Event Type
| Type |
|---|
| System.EventHandler<DiagramConnectorSourcePointChangedEventArgs> |
TargetPointChanged
The target-end counterpart of SourcePointChanged.
Declaration
public event EventHandler<DiagramConnectorTargetPointChangedEventArgs> TargetPointChanged
Event Type
| Type |
|---|
| System.EventHandler<DiagramConnectorTargetPointChangedEventArgs> |
TextEdited
Raised after a double-tap/double-click label edit is committed in the WebView (the user typed new text into a node's or connector's annotation and then unfocused it), once the corresponding Content has already been updated on the native side. Added as a diagnostic hook: subscribing to this (with a breakpoint, a System.Diagnostics.Debug.WriteLine(System.String), or a bound label) confirms whether an edit is actually making it from the WebView back to the native model at all, without needing a JavaScript debugger attached to the hosted page.
Declaration
public event EventHandler<DiagramTextEditedEventArgs> TextEdited
Event Type
| Type |
|---|
| System.EventHandler<DiagramTextEditedEventArgs> |