Building a WinForms PDM From Scratch

By Thomas Smith on July 8, 2025

How Habasit America slashed drawing-search time in half by layering SOLID architecture, dependency-injection, and three rapid WinForms sprints over a massive CAD library.

WinForms.NET 8Dependency InjectionSOLIDDesign PatternsSDLCPDMCAD Automation
Sprint-3 full UI

Special-build belt drawings once hid behind cryptic numbers. By introducing attribute-level parsing, a lightning-fast filter panel, and clean Dependency Injection (DI), our WinForms PDM now surfaces matches in ~2 seconds instead of 5 plus — a 50 % improvement that lets engineers reuse instead of redraw.

Project Context

Habasit America maintains more than 17 000 legacy belt drawings. Searching by number alone forced tribal knowledge and slowed onboarding. Stakeholders set a KPI to double daily reuse hits within one fiscal quarter.

We opted for a lean WinForms MVP because operators already live in Windows Explorer and SolidWorks; no new runtime permissions were needed. Source code lives in a public GitHub repo (view here).

SDLC Highlights in Three Sprints

Problem: Search limited to filename; junior drafters spent ~5 minutes hunting.

Solution: Break drawing number into 14 attributes (series, width, color, etc.) then expose each as a filterable column.

Impact: Lookup time dropped by half; tribal memory no longer required.

  • Stakeholder workshops gathered 12 must-have attributes and 8 nice-to-haves.
  • Used MoSCoW prioritisation to shape the sprint backlog.
  • Dependency Injection (DIP)Program.cs boots ServiceCollection then resolves Form1; forms no longer create their own services.
  • Repository / Service patternDrawingFileService abstracts JSON vs network lookup.
  • StrategyIDrawingNumberDecipherService is pluggable for future product lines.
  • SOLID guidance ensures each class has one reason to change.
  • Sprint 1 UI

    Problem: Static filter mock-up, no DI.

    Solution: Hooked DataGrid double-buffering & basic search.

    Impact: First demo proved concept to leadership.

    Sprint 2 UI

    Problem: Filters slow with 10 000+ rows.

    Solution: Parallel LINQ (PLINQ) on file scan; binding lists.

    Impact: Load time dropped from 18 s → 6 s.

    Sprint 3 UI

    Problem: Context menu & attribute panel missing.

    Solution: Added right-click actions, logger, live decipher grid.

    Impact: Users complete full lookup + open drawing in under 30 s.

  • xUnit tests validate 40 + drawing-number permutations.
  • Smoke-test script ensures DI container builds on startup.
  • ClickOnce installer to internal file-share; config JSON points to K:\ drive.
  • Serilog sinks to rolling JSON for analytics.
  • Future: migrate UI to Blazor Hybrid while reusing all services.
  • Key Code Excerpts

    // Program.cs — DI bootstrap
    var services = new ServiceCollection();
    services.AddScoped<IDrawingFileService, DrawingFileService>();
    services.AddScoped<IDrawingNumberDecipherService, DrawingNumberDecipherService>();
    services.AddHttpClient();
    services.AddScoped<Form1>();
    using var provider = services.BuildServiceProvider();
    Application.Run(provider.GetRequiredService<Form1>());
    // DrawingNumberDecipherService.cs — Strategy + SRP
    foreach (var (attr, max, lookup) in metadata)
    {
        string code = drawingNumber.Substring(idx, max);
        idx += max;
        string value = lookup(code); // maps code → human attr
        result[attr] = (code, value);
        _logger.LogInformation("{Attr}:{Code}->{Val}", attr, code, value);
    }

    Before vs After

    • Lookup time — ~5 min → < 2.5 min (-50 %).
    • Daily reused drawings — 8 → 18 on average.
    • Onboarding ramp-up — 2 weeks → 3 days.

    Three sprints, clean architecture, and relentless user feedback turned a shared drive into an insight-driven PDM. Sprint-4 will layer AI suggestions and Blazor-Hybrid UI — stay tuned!