Skip to main content

First WinForms App

This guide builds the smallest WinForms host window: type text, click send, receive the virtual-channel echo, and show channel state.

Run the Sample

From the repository code directory:

dotnet run --project samples/Zeus.Samples.WinForms.QuickStart

The window should show Open, send PING, and display the echo.

Required Packages

dotnet add package Zeus.Communications
dotnet add package Zeus.Presentation.WinForms

Project file:

<TargetFramework>net8.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>

Minimal Form Code

using System.Text;
using Zeus;

public sealed class MainForm : Form
{
private readonly TextBox _input = new() { Text = "PING", Dock = DockStyle.Fill };
private readonly Button _send = new() { Text = "Send", Dock = DockStyle.Fill };
private readonly Label _state = new() { Dock = DockStyle.Fill };
private readonly Label _echo = new() { Dock = DockStyle.Fill };
private readonly IChannel _meter;

public MainForm()
{
Text = "Zeus WinForms QuickStart";

var layout = new TableLayoutPanel { Dock = DockStyle.Fill, ColumnCount = 2, RowCount = 4 };
layout.Controls.Add(new Label { Text = "Send" }, 0, 0);
layout.Controls.Add(_input, 1, 0);
layout.Controls.Add(_send, 1, 1);
layout.Controls.Add(new Label { Text = "State" }, 0, 2);
layout.Controls.Add(_state, 1, 2);
layout.Controls.Add(new Label { Text = "Echo" }, 0, 3);
layout.Controls.Add(_echo, 1, 3);
Controls.Add(layout);

var attachment = this.AttachZeus(builder => builder.AddVirtualChannel("meter"));
_meter = attachment.Host.Channels.Get("meter");
_meter.BindState(_state);
_meter.BindTo(_echo);
_meter.BindEnabled(_send);

_send.Click += async (_, _) =>
{
await _meter.WriteAsync(Encoding.UTF8.GetBytes(_input.Text));
};
}
}

Why No Manual Invoke

Serial and TCP receive callbacks usually run outside the UI thread. BindTo, BindState, and BindEnabled marshal updates through the WinForms adapter, so you do not need to write InvokeRequired in every form.

Replace with a Real Serial Port

Change only the registration line:

var attachment = this.AttachZeus(builder => builder.AddSerialPort("meter", "COM3", 9600));

The binding and send code remain unchanged.

Next: WinForms Adapter or Serial Port.