DiagramValidator runs a set of rules over the current components and connection lines and returns a list of DiagramIssue records. The editor sample runs it from the Validate command and reports the summary in the status bar; hosts can run it before saving, exporting or executing a workflow.

Running Validation

The validator owns its rule list. Add the defaults, optionally add your own rules, then validate the diagram's current contents:

var validator = new DiagramValidator();
validator.AddDefaultRules();

List<DiagramIssue> issues = validator.Validate(
    drawingManager.GetComponents().ToList(),
    drawingManager.GetLines());

int errors   = issues.Count(i => i.Severity == DiagramIssueSeverity.Error);
int warnings = issues.Count(i => i.Severity == DiagramIssueSeverity.Warning);

foreach (var issue in issues)
{
    Console.WriteLine($"[{issue.Severity}] {issue.RuleName}: {issue.Message}");
    if (!string.IsNullOrEmpty(issue.FixSuggestion))
        Console.WriteLine($"    fix: {issue.FixSuggestion}");
}

Built-in Rules

AddDefaultRules() registers six rules:

RuleDetects
OrphanNodeRuleComponents with zero incoming and zero outgoing connections.
CycleDetectionRuleCycles in the diagram that may cause infinite loops when executed.
DeadEndNodeRuleNodes that have inputs but no outputs (or vice versa) where the family expects flow-through.
OverlappingComponentsRuleComponents whose bounds overlap, hiding content on the canvas.
EmptyDiagramRuleA diagram with no components at all (for example before an export or execution).
UnconnectedPortRulePorts that should be wired but have no connection.

Issues and Severities

MemberTypeDescription
MessagestringHuman-readable description of the problem.
SeverityDiagramIssueSeverityInfo, Warning (default) or Error.
ComponentSkiaComponentThe component involved, when the issue is component-specific.
LineIConnectionLineThe connection involved, when the issue is line-specific.
RuleNamestringName of the rule that produced the issue (for filtering or suppression).
FixSuggestionstringOptional hint on how to resolve the problem.

Issues are data, not exceptions: validation never throws for a malformed diagram, it reports. That makes it safe to run on every save.

Custom Rules

Implement IDiagramRule and register the rule with AddRule. Rules receive the full component and line lists and yield issues:

public sealed class NamingConventionRule : IDiagramRule
{
    public string Name => "NamingConvention";
    public string Description => "Process nodes must use verb phrases (e.g. 'Validate Order').";

    public IEnumerable<DiagramIssue> Validate(
        IReadOnlyList<SkiaComponent> components,
        IReadOnlyList<IConnectionLine> lines)
    {
        foreach (var node in components.OfType<ProcessNode>())
        {
            if (!string.IsNullOrWhiteSpace(node.Label) &&
                char.IsLower(node.Label.TrimStart()[0]))
            {
                yield return new DiagramIssue
                {
                    RuleName = Name,
                    Severity = DiagramIssueSeverity.Info,
                    Component = node,
                    Message = $"'{node.Label}' should start with a capital letter.",
                    FixSuggestion = "Rename the node using a verb phrase."
                };
            }
        }
    }
}

// Register and run
var validator = new DiagramValidator();
validator.AddDefaultRules();
validator.AddRule(new NamingConventionRule());
var issues = validator.Validate(components, lines);

Rules are independent and order-insensitive; Rules exposes the registered list if you want to display or toggle them in a UI.