Overview

Beep.Forms brings Oracle Forms-style development to modern .NET. One engine — BeepDM — owns every piece of form behavior: blocks, items, triggers, LOVs (lists of values), validations, master-detail relations, and menus. The UI layer never duplicates that behavior; it only renders controls and forwards user actions (navigation, query-by-example, CRUD, menu clicks) straight to the engine through public interfaces (IUnitofWorksManager, IDMEEditor, IBeepFormsHost, IBlockView).

The repository is five projects around that one engine:

  • TheTechIdea.Beep.Forms.IDE — the Visual Studio extension: a visual Object Navigator for authoring blocks, triggers, LOVs, validations, master-detail relations, and the form menu. It writes registrations into your form's own .Designer.cs / .xaml.cs and reads them back through the same marker contract — the IDE authors, it never runs behavior itself.
  • TheTechIdea.Beep.Forms.WinForms — the WinForms runtime (WinFormFormHost, block/field hosts, status bar).
  • TheTechIdea.Beep.Forms.Wpf — the WPF runtime (BeepWpfForms, block/field hosts, status bar, LOV/alert dialogs). No System.Windows.Forms, no System.Drawing.
  • TheTechIdea.Beep.Forms.Examples.WinForms / .Examples.WPF — runnable demo apps, each with a headless --selftest switch.

Beep.Forms.slnx opens all five together. Target framework: net10.0-windows, LangVersion pinned to 12.0 — this is a deliberate, documented constraint (C# 13/14 will not compile), not an oversight to "fix."

Payments

If a Beep.Forms app ever needs to charge or check out a customer, integrate with the Beep.DoitAll Payments API over HTTP — see Architecture for details. Never embed Beep.DoitAll in-process (it's a separate SaaS) and never hand-roll a vendor SDK integration directly.

🚀 Start here

Author a form visually, then run the same definition on either UI stack.

The registration pattern, at a glance

Every piece of form behavior is a registration against the engine's IUnitofWorksManager — a trigger, an LOV, a validation rule, or a master-detail relation. This is real, runnable code from the shipped Order Entry example (see End-to-End Example for the full walkthrough):

From the shipped Order Entry example

manager.Triggers.RegisterTrigger(new TriggerDefinition(
    TriggerType.WhenValidateItem, TriggerScope.Item)
{
    TriggerId = "ord.qty.WhenValidateItem",
    BlockName = "Ord", ItemName = "Qty", Handler = OnValidateQty,
});

manager.LOV.RegisterLOV("Ord", "Qty", new LOVDefinition
{
    LOVName = "QtyLov", DataSourceName = "DemoDb",
    EntityName = "orderlines", DisplayField = "Qty", ReturnField = "Id",
});

manager.CreateMasterDetailRelation("Ord", "OrdLine", "Id", "OrderId");

The Object Navigator IDE extension writes exactly this shape of code into your form's designer file when you author visually — the generated code and the hand-written example are the same contract.

Explore the docs

Architecture

Five projects, one engine, the platform-independence rule, and the Oracle-naming legal boundary.

Authoring (IDE)

The Object Navigator: context menus per node type, the toolbar, and how trigger names resolve to the engine's TriggerType enum.

WinForms Runtime

WinFormFormHost: Definition, FormsManager, auto-wiring, and multi-block hosting.

WPF Runtime

BeepWpfForms: the same host API, one active block per host, and the dialog set.

End-to-End Example

The real Order Entry form: master-detail, triggers, LOV, validation, CALL_FORM, and a timer.

Remote UI Limitations

What doesn't transport across the IDE's out-of-process UI boundary, and the documented workaround for each.