Skip to main content

WPF Adapter

The WPF adapter uses Dispatcher to marshal channel events and point changes back to the UI thread, and provides TextBlock bindings and binding sources.

var attachment = this.AttachZeus(builder => builder.AddVirtualChannel("meter"));
var meter = attachment.Host.Channels.Get("meter");
meter.BindTo(EchoText);
meter.BindEnabled(SendButton);
DataContext = meter.AsBindingSource(this);
<TextBlock Text="{Binding LastText}" />
<TextBlock Text="{Binding StateText}" />

Assembly: Zeus.Presentation.Wpf with target framework net8.0-windows.

APIs

APIPurpose
Window.AttachZeus(...)Starts on Loaded, disposes on Closed
BindTo / BindTextWrites received data to TextBlock.Text
BindStateDisplays channel state
BindEnabledSets UIElement.IsEnabled, defaulting to enabled only when Open
AsBindingSource(element)Publishes channel property changes through the element dispatcher
points.BindTo(...)Writes point values to text blocks
points.BindSnapshot(...)Pushes full point snapshots to the UI thread
points.BindHistory(...)Pushes successful sample history to the UI thread
points.AsBindingSource(...)Single-point INotifyPropertyChanged projection
points.AsHistoryBindingSource(...)Point-history projection
points.BindAlarmBackground / BindAlarmForegroundChanges colors based on alarm/error state
points.BindWriteBackBinds a button click to Points.WriteAsync

ChannelBindingSource exposes Name, State, StateText, LastText, LastHex, and ReceivedCount.

PointBindingSource exposes Name, QualifiedName, Value, Text, Error, HasError, AlarmState, IsAlarmed, UpdatedAt, and Writable.

Point Binding

TemperaturePanel.DataContext = points.AsBindingSource("temperature", this);
<TextBlock Text="{Binding Text}" />
<TextBlock Text="{Binding AlarmState}" />
<TextBlock Text="{Binding Error}" />

Quick direct binding also works:

points.BindTo("temperature", TemperatureText, value => $"{value:0.0} C");
points.BindAlarmBackground("temperature", TemperatureText);
points.BindEnabled("setpoint", WriteButton);
points.BindWriteBack(
"setpoint",
SetpointTextBox,
WriteButton,
text => double.Parse(text, CultureInfo.InvariantCulture),
ex => MessageBox.Show(this, ex.Message, "Write failed", MessageBoxButton.OK, MessageBoxImage.Warning));

Existing Prism / DI Apps

Keep your application container in charge of windows, navigation, and view models. Register Zeus as a singleton service and start/stop it at app lifecycle boundaries.

var zeus = ZeusHost.Create(builder =>
{
builder.AddSerialPort("meter", "COM3", 9600);
builder.AddAcquisition(TimeSpan.FromMilliseconds(500));
});

containerRegistry.RegisterInstance<IZeusHost>(zeus);
containerRegistry.RegisterInstance<IChannelRegistry>(zeus.Channels);
containerRegistry.RegisterInstance<IPointTable>(zeus.Points);

Prefer injecting narrower interfaces such as IChannelRegistry or IPointTable into view models.