Skip to content

Error Reporting

g$ edited this page Feb 7, 2018 · 1 revision

Nothing is more frustrating than trying to "bring up" a chart or other complicated piece of XAML!

The Chart provides an error reporting event that you can attach code to, and be notified of configuration errors in the chart. This can speed up the debugging process when a chart fails to render correctly.

The most-common cause of mis-configuration revolves around the x:Name attribute on XAML elements, and the corresponding chart component’s attributes, e.g. ValueLabels.SourceName. If any "names" fail to locate their targets, the component will not be able to render anything.

Error Info Event

This is a handler you can attach from the XAML to your code-behind:

<yacc:Chart x:Name="chart" Style="{StaticResource Chart}" ChartError="Chart_ChartError" ...

And the easiest thing to do there is just "log it"

private void Chart_ChartError(Chart sender, ChartErrorEventArgs args) {
	foreach(var ev in args.Results) {
		Debug.WriteLine($"chart error {ev.Source}\t{String.Join(",", ev.MemberNames)}: {ev.ErrorMessage}");
	}
}

This will show up in the Output Window during debugging. Notice that errors are batched to reduce the number of calls to the handler.

Error Info

The framework’s ValidationResult is the basis for reporting errors in YACC, which uses a subclass ChartValidationResult that includes additional details.

Sending Error Info

The primary place a ChartComponent sends error info, is in the IRequireEnterLeave.Enter method, when it enters the visual tree.

For example, a DataSeriesWithAxes requires the two axes referred to in the XXXAxisName properties.

protected void EnsureAxes(IChartComponentContext icrc) {
	if (ValueAxis == null && !String.IsNullOrEmpty(ValueAxisName)) {
		ValueAxis = icrc.Find(ValueAxisName) as IChartAxis;
	} else {
		if (icrc is IChartErrorInfo icei) {
			icei.Report(new ChartValidationResult(NameOrType(), $"Value axis '{ValueAxisName}' was not found", new[] { nameof(ValueAxis), nameof(ValueAxisName) }));
		}
	}
	if (CategoryAxis == null && !String.IsNullOrEmpty(CategoryAxisName)) {
		CategoryAxis = icrc.Find(CategoryAxisName) as IChartAxis;
	} else {
		if (icrc is IChartErrorInfo icei) {
			icei.Report(new ChartValidationResult(NameOrType(), $"Category axis '{CategoryAxisName}' was not found", new[] { nameof(CategoryAxis), nameof(CategoryAxisName) }));
		}
	}
}

This is a helper method that resolves the ChartComponent names, and generates error info if that fails. It is used by subclasses:

void IRequireEnterLeave.Enter(IChartEnterLeaveContext icelc) {
	EnsureAxes(icelc as IChartComponentContext);
	...
}

Notice that IChartErrorInfo is not a required interface on the context. Indeed, there are places where the Chart deliberately refuses to collect error info, like in the render pipeline, which executes very frequently, and would just make the same messages over and over.

Clone this wiki locally