Enabling SmartDatasetAdapter Counts on Tab-Pages in static forms

Enabling SmartDatasetAdapter Counts on Tab-Pages in static forms

Overview

The Consultingwerk.Windows.Framework.Repository.Rendering.DataSourceRecordCountProvider displays a record count next to a tab's text (for example "Pages (12)") by listening to the data adapter's retrieve / create / update / delete events. Until SCL-5238 the provider was only wired up automatically by DynamicFormRenderingService for repository-rendered forms (DynamicForm).

SCL-5238 made this feature part of every SmartWindowForm:

  • SmartWindowForm now implements IHasTabDataSourceCount and owns a DataSourceRecordCountProvider property. Subclasses no longer declare a field, implement the interface, or write their own Initialize() / Shutdown() plumbing — SmartWindowForm:OnLoad calls Initialize() and SmartWindowForm:OnFormClosed calls Shutdown() automatically.

  • A new typed AddDataSourceToTab(SmartDatasetAdapter, UltraTab, character) overload on the provider lets static forms register their adapters by direct field reference instead of by name.

  • Both SmartBusinessEntityAdapter and SmartDatasetChildAdapter are supported because the provider now operates against their common base class SmartDatasetAdapter. SDCA records live in the parent's dataset and never trigger a backend count roundtrip — the count is read locally from BindingSource:Count.

Reference implementation: Consultingwerk.Windows.Framework.Repository.Object.SmartObjectMasterForm — the Repository Object Maintenance form that displays counts on its Pages, Instances, Links and Where Used tabs.

When to use this

  • You have a static SmartWindowForm with an UltraTabControl.

  • One or more tabs are bound to a SmartBusinessEntityAdapter or SmartDatasetChildAdapter.

  • You want the tab text to show a live record count, e.g. "Instances (5)".

For repository-rendered forms (DynamicForm) the wiring already happens automatically — you do not need this guide.

Steps

1. Add the required using statement

Add a using for the Repository.Rendering namespace (only needed for the DataSourceRecordCountProvider type itself; the property and interface come from SmartWindowForm):

using Consultingwerk.Windows.Framework.Repository.Rendering.* from propath.

2. Register your adapter / tab pairs

Use the typed overload DataSourceRecordCountProvider:AddDataSourceToTab(SmartDatasetAdapter, UltraTab, character) to register every adapter whose count should appear on a tab. Pass the tab's current Text as the pattern — the provider automatically appends " (&1)" when the pattern does not already contain a &1 placeholder, so localized tab labels work out of the box.

Concentrate the wiring in a single helper method:

/** * Purpose: Wires up the DataSourceRecordCountProvider for the four tabs * that should display a record count in their tab text * Notes: The provider listens to the adapters' RetrieveData / record * maintenance events and updates the corresponding UltraTab Text. * Initialize() / Shutdown() are driven by SmartWindowForm. */ method protected void InitializeRecordCountProvider (): this-object:DataSourceRecordCountProvider = new DataSourceRecordCountProvider (this-object). this-object:DataSourceRecordCountProvider:AddDataSourceToTab (this-object:pagesAdapter, this-object:ultraTabControl1:Tabs["pages":u], this-object:ultraTabControl1:Tabs["pages":u]:Text). this-object:DataSourceRecordCountProvider:AddDataSourceToTab (this-object:instancesAdapter, this-object:ultraTabControl1:Tabs["instances":u], this-object:ultraTabControl1:Tabs["instances":u]:Text). this-object:DataSourceRecordCountProvider:AddDataSourceToTab (this-object:linksAdapter, this-object:ultraTabControl1:Tabs["links":u], this-object:ultraTabControl1:Tabs["links":u]:Text). this-object:DataSourceRecordCountProvider:AddDataSourceToTab (this-object:smartBusinessEntityAdapter2, this-object:ultraTabControl1:Tabs["whereused":u], this-object:ultraTabControl1:Tabs["whereused":u]:Text). end method .

In SmartObjectMasterForm the four registered adapters are a mix of types — three SmartDatasetChildAdapter instances (pagesAdapter, instancesAdapter, linksAdapter) and one SmartBusinessEntityAdapter (smartBusinessEntityAdapter2). They all flow through the same overload because SmartDatasetAdapter is the common base class.

Tip: You do not need to declare a field for the provider, implement IHasTabDataSourceCount, or call Initialize() / Shutdown() yourself. All of that lives on SmartWindowForm.

3. Call the helper from OnLoadbefore `super:OnLoad(e)*

SmartWindowForm:OnLoad calls DataSourceRecordCountProvider:Initialize() near the end of its own body (right before the ui-catch.i include). The registration must therefore be in place before you call super:OnLoad(e):

method protected override void OnLoad (e as System.EventArgs): define variable oValueListProvider as IValueListProvider no-undo. define variable oPluginLoader as ISmartObjectMasterFormPluginLoader no-undo. /* ... any work that must happen before super:OnLoad ... */ /* Register the four tabs/adapters before super:OnLoad so that the SmartWindowForm:OnLoad call below can drive Initialize() on the provider once the registration is in place. */ this-object:InitializeRecordCountProvider () . super:OnLoad (e) . /* ... rest of the OnLoad logic ... */ end method .

4. (Nothing else)

You do not need to override OnFormClosed. SmartWindowForm:OnFormClosed already calls DataSourceRecordCountProvider:Shutdown() for you.

Pattern customization

The third argument to AddDataSourceToTab is the text pattern applied to the tab. Two forms are supported:

  • Plain label — e.g. "Instances". The provider rewrites it to "Instances (&1)" internally and substitutes the count for &1.

  • Custom pattern — supply your own &1 placeholder if you want different formatting, e.g. "Instances [&1]" or "&1 instance(s)".

Passing the tab's current Text (as in the sample above) preserves any localized resource value applied by InitializeComponent.

What the provider does behind the scenes

For each registered adapter the provider subscribes to BeforeRetrieveData, AfterRetrieveData, QueryClosed, SmartNavigationTargetPositionChanged, AfterCreateRecord, AfterUpdateRecord and AfterDeleteRecord. After each retrieve it inspects the adapter:

  • For a SmartDatasetChildAdapter the count is always read locally from BindingSource:Count — SDCA records live in the parent's dataset and never trigger a backend roundtrip.

  • For a SmartBusinessEntityAdapter whose binding source already holds the full result set (Batching = false) the count is also read locally — no extra server round-trip.

  • Otherwise the CountRecordsBusinessTask is invoked on the server to fetch the row count for the current query.

The matching UltraTab:Text is then updated through the registered pattern.

Reference

Class / interface

Purpose

Class / interface

Purpose

Consultingwerk.SmartComponents.Base.SmartWindowForm

Owns the DataSourceRecordCountProvider property and drives its Initialize() / Shutdown() lifecycle. Implements IHasTabDataSourceCount.

Consultingwerk.Windows.Framework.Repository.Rendering.DataSourceRecordCountProvider

The provider that listens to adapter events and updates tab text. Exposes both the name-based and the typed AddDataSourceToTab overloads.

Consultingwerk.Windows.Framework.Repository.Rendering.IHasTabDataSourceCount

Marker interface implemented by SmartWindowForm — derived forms inherit it for free.

Consultingwerk.SmartComponents.Base.SmartDatasetAdapter

Common base class of SmartBusinessEntityAdapter and SmartDatasetChildAdapter — the parameter type accepted by the typed AddDataSourceToTab overload.