Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: UIElement/FrameworkElement should expose protected method to add/initialize VisualTree #5530

Open
michael-hawker opened this issue Jul 21, 2021 · 3 comments
Labels
feature proposal New feature proposal needs-winui-3 Indicates that feature can only be done in WinUI 3.0 or beyond. (needs winui 3) product-winui3 WinUI 3 issues team-Controls Issue for the Controls team wct

Comments

@michael-hawker
Copy link
Collaborator

michael-hawker commented Jul 21, 2021

Proposal: UIElement/FrameworkElement should expose protected method to add/initialize VisualTree

Follow-up from discussion on docs repo here: MicrosoftDocs/winrt-api#646

Summary

Currently, especially in C#, it's not possible to inherit directly from FrameworkElement for a low-level component. Even in WinUI 2 with C++ here, while they look like they're inheriting from FrameworkElement, they're really using Panel (see DeriveFromPanelHelper_base) as an intermediary even if only a single child is expected.

The ability to initialize a Child or Children property into the Visual Tree that's being created on a subclass of FrameworkElement is not exposed even as a protected member within the framework. This means that while you can write code that inherits directly from FrameworkElement, there's no way to get it to render as it can't be added to the VisualTree itself.

Rationale

In the Windows Community Toolkit, we wanted to add a low-level component akin to Viewbox for constraining to a specific aspect ratio. It made sense to make it a single-child control from FrameworkElement, but we can't do that directly as we can't add the Child property we create to the Visual Tree. See CommunityToolkit/WindowsCommunityToolkit#4104.

Instead we need to inherit from Panel if we want something simple, but then that allows for multiple children to be added (which is odd for this scenario) OR we need to inherit from ContentPresenter which does more than we need it to do with templating support.

  • Would allow library developers to also develop lower-level components without the overhead of the high-level abstractions.

Scope

Capability Priority
This proposal will allow developers to accomplish initialize and render a low-level UI component Must
This proposal will allow end users to accomplish react to remove and replace content when a developer changes the content of the sub-classed control Must
This proposal will allow developers to create an element which accepts multiple children Could

API Proposal

Example of what a proposed API could look like with a protected AddChild and RemoveChild method for UIElement:

  public MyClass : FrameworkElement
  {
      propdp UIElement Child; // Shorthand
      
      private static void ChildPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {      
          if (d is FrameworkElement element && e.OldValue != e.NewValue)
          {
             element.RemoveChild(e.OldValue); // new protected method
             
             if (e.NewValue != null)
             {
                 element.AddChild(e.NewValue); // new protected method
             }
          }
      }
 }

Open Questions

  • I think it makes sense by default that a FrameworkElement would have a single child as a root for folks to subclass from. Otherwise if they accept multiple-children, it feels like they'd be a Panel based implementation at that point? I don't know the implementation details of Panel so not sure where it makes sense to optimize for the single vs. multi-children support in the stack.
  • I noticed some controls like ParallaxView expose Child as a Dependency Property, but others like Border do not. Is there a reason? Is it required to be a DP to support removing/adding dynamically to the content of the control?
  • There's also the ChildTransitions property on many FrameworkElement subclasses, there'd probably at least need to be documentation on how to add that into this scenario as well.
  • WPF had the Decorator subclass as a mirror to Panel but that took a single child. Does it make sense to provide that as a new base for Border/Viewbox like it was in WPF and keep more of the abstraction, but provide a lighter-weight model to build off-of.
  • Should Viewbox be ViewBox??? 😋
@michael-hawker michael-hawker added feature proposal New feature proposal needs-winui-3 Indicates that feature can only be done in WinUI 3.0 or beyond. (needs winui 3) wct labels Jul 21, 2021
@ghost ghost added the needs-triage Issue needs to be triaged by the area owners label Jul 21, 2021
@StephenLPeters StephenLPeters added product-winui3 WinUI 3 issues team-Framework and removed needs-triage Issue needs to be triaged by the area owners labels Jul 22, 2021
@StephenLPeters
Copy link
Contributor

@MikeHillberg and @chrisglein FYI

@michael-hawker
Copy link
Collaborator Author

michael-hawker commented Sep 23, 2022

Hit this working on my polyfill for Adorners as well as AdornerDecorator really just wants to be a Decorator (i.e. FrameworkElement in UWP/WinUI) and then set two children instead transparently even though in XML it has the single Child content property.

@michael-hawker
Copy link
Collaborator Author

Bumping, though think this is a feature request, based on #8638

@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Aug 22, 2023
@bpulliam bpulliam removed the needs-triage Issue needs to be triaged by the area owners label Oct 18, 2023
@bpulliam bpulliam added the team-Controls Issue for the Controls team label May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature proposal New feature proposal needs-winui-3 Indicates that feature can only be done in WinUI 3.0 or beyond. (needs winui 3) product-winui3 WinUI 3 issues team-Controls Issue for the Controls team wct
Projects
None yet
Development

No branches or pull requests

4 participants