Skip to content

Add IInterceptedRelatedManager opt-in seam to BindingContext/RelatedCurrencyManager#28

Draft
Copilot wants to merge 3 commits into
masterfrom
copilot/add-optional-extension-to-bindingcontext
Draft

Add IInterceptedRelatedManager opt-in seam to BindingContext/RelatedCurrencyManager#28
Copilot wants to merge 3 commits into
masterfrom
copilot/add-optional-extension-to-bindingcontext

Conversation

Copilot AI commented Jun 18, 2026

Copy link
Copy Markdown

On .NET Framework, ZBindingContext intercepted BindingContextHashtable.Add to swap in a custom CurrentChanged handler before the child manager was primed — so the empty-parent Everett AddNew()/CancelCurrentEdit() branch was never reached. On .NET 10 the backing store is a Dictionary, making that interception impossible. The previous RewireParentChangeHandler approach fired after construction, meaning ParentManager_CurrentItemChanged (and thus AddNew()) already ran before any rewire could occur.

This PR introduces a factory-based opt-in seam that installs a custom handler before the first prime, exactly replicating Framework ordering — with zero overhead on the default path.

BindingContext

  • Added BindingContext.IInterceptedRelatedManager — public nested interface (ParentHasRows, RaiseParentCurrentItemChanged, BindToEmptyParentPlaceholder) enabling a subclass in another assembly to drive the internal RelatedCurrencyManager without reflection.
  • Added protected virtual EventHandler? CreateInterceptedParentHandler(IInterceptedRelatedManager) — returns null by default; overriding activates the opt-in path.
  • Added private CreateRelatedCurrencyManager(...) helper — factory delegate is only allocated when GetType() != typeof(BindingContext), guaranteeing no overhead for stock WinForms.
  • Removed static RewireRelatedCurrencyManagerParent(...) (superseded).

RelatedCurrencyManager

  • New overloaded constructor accepts Func<RelatedCurrencyManager, EventHandler>?; the factory is invoked before Bind() so _interceptedParentHandler is set before the first prime.
  • Bind() gates on _interceptedParentHandler: default path calls ParentManager_CurrentItemChanged as before; opt-in path calls the supplied handler (bypassing the Everett AddNew() branch).
  • WireParentManager/UnwireParentManager subscribe to CurrentChanged (not CurrentItemChanged) when a handler is active.
  • Explicit BindingContext.IInterceptedRelatedManager implementation added.
  • RewireParentChangeHandler() removed (superseded).

Usage pattern

// In a derived BindingContext (e.g. in another assembly):
protected override EventHandler? CreateInterceptedParentHandler(
    BindingContext.IInterceptedRelatedManager relatedManager)
{
    return (sender, e) =>
    {
        if (relatedManager.ParentHasRows)
            relatedManager.RaiseParentCurrentItemChanged(sender, e);
        else
            relatedManager.BindToEmptyParentPlaceholder(new TempList());
    };
}

API surface

PublicAPI.Unshipped.txt updated: RewireRelatedCurrencyManagerParent removed; IInterceptedRelatedManager interface and CreateInterceptedParentHandler virtual added.

Copilot AI added 2 commits June 18, 2026 05:45
…atedCurrencyManager

- Add BindingContext.IInterceptedRelatedManager public nested interface with ParentHasRows,
  RaiseParentCurrentItemChanged, and BindToEmptyParentPlaceholder members
- Add BindingContext.CreateInterceptedParentHandler protected virtual factory (returns null by default)
- Add BindingContext.CreateRelatedCurrencyManager private helper; replace direct construction in EnsureListManager
- Remove BindingContext.RewireRelatedCurrencyManagerParent (superseded by new design)
- Add RelatedCurrencyManager second constructor accepting Func<RelatedCurrencyManager, EventHandler>? factory
- Implement IInterceptedRelatedManager explicitly on RelatedCurrencyManager
- Update WireParentManager/UnwireParentManager for intercepted handler path
- Update Bind() to prime via intercepted handler when present (avoids constructor-time AddNew)
- Remove RelatedCurrencyManager.RewireParentChangeHandler (superseded)
- Update PublicAPI.Unshipped.txt for new/removed API surface
- Add unit tests for default path and intercepted handler path
Copilot AI changed the title [WIP] Add optional extension point to RelatedCurrencyManager Add IInterceptedRelatedManager opt-in seam to BindingContext/RelatedCurrencyManager Jun 18, 2026
Copilot AI requested a review from FahmiFuzi June 18, 2026 05:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants