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

Align TemplatedParent with WinUI #15749

Closed
Tracked by #8339
MartinZikmund opened this issue Mar 5, 2024 · 1 comment
Closed
Tracked by #8339

Align TemplatedParent with WinUI #15749

MartinZikmund opened this issue Mar 5, 2024 · 1 comment
Labels
area/skia/lifecycle ✏️ area/skia/stability ✏️ difficulty/medium 🤔 Categorizes an issue for which the difficulty level is reachable with a good understanding of WinUI kind/breaking-change 💥 Categorizes an issue or PR as requiring a breaking change to be fixed. kind/enhancement New feature or request project/navigation-lifecycle 🧬 Categorizes an issue or PR as relevant to the navigation and lifecycle (NavigationView, AppBar, ...)

Comments

@MartinZikmund
Copy link
Member

What would you like to be added

Currently we have TemplatedParent as inherited dependency property, which causes various kinds of issues.

Why is this needed

In WinUI, TemplatedParent is a parse-time only concept and may be set once and only once, see CDependencyObject.h:

// What is a templated parent exactly? What does it mean in the context of our framework? These are good questions
// that have muddy answers. A template parent is a parse-time concept that should ONLY be used in the context of
// features that work using the parse-time XAML tree. Today that list of features includes NameScoping and TemplateBindings,
// which are features that operate on the tree as it appears in XAML, not as it appears at runtime. (they are
// often but not always identical in many ways)
//
// You'll find corners of the platform where we directly instantiate an object and then set its TemplateParent. This
// is an evil, bad thing to do. It makes no sense if you accept the One True Definition of a template parent above.
//
// What this code is trying to do is usually one of the following scenarios:
// - Make FindName work for Template NameScopes when using the created object as a reference object: FindName should
//   not work here by design and now you've created an object that doesn't have the IsTemplateNameScopeMember flag set
//   which means all kinds of assumptions for how namescopes should be registered are now invalid.
// - Use GetTemplateParent as a pseudo 'GetOwningControl'. The platform has a strong idea of controls as being little
//   self-contained units and we anchor a lot of stuff to controls like the UIA tree. Over time it's been noticed
//   that calling GetTemplateParent is a way to quickly get the owning control for a UIElement. This is an invalid
//   invarient. Sometimes controls have elements dynamically created, and sometimes things that arne't controls
//   are TemplateParents. In this case the code should simply traverse up the tree looking for the correct type.
//
// TemplateParents come from ControlTemplate parses, and from the Data and Item templates on Presenters. You should
// NOT set this yourself, as any changes or improvements we make that take advantage of template parse origination will
// need to take your special out-of-band set into account.
_Check_return_ HRESULT SetTemplatedParent(_In_ CDependencyObject* parent)
{
    // These are the only types that serve as templated parents today.
    ASSERT(parent && (
        parent->OfTypeByIndex<KnownTypeIndex::ContentPresenter>() ||
        parent->OfTypeByIndex<KnownTypeIndex::Control>() ||
        parent->OfTypeByIndex<KnownTypeIndex::ItemsPresenter>()));

    // SetTemplatedParent is a single-shot operation at parse time.
    ASSERT(GetTemplatedParent() == nullptr);

    SetTemplatedParentImpl(parent);
    return S_OK;
}

And framework.cpp:

// Sets the templated parent of this object, it should only be set once
// as the templated parent should not change during the life of an FE
void CFrameworkElement::SetTemplatedParentImpl(_In_ CDependencyObject* parent)
{
    ASSERT(m_pTemplateBindingData == nullptr);
    m_pTemplateBindingData.reset(new TemplateBindingData);
    // Create a WeakRef to the TemplatedParent.  It could be released and at that time, it would
    // be too tedious to unhook all the nested children.
    m_pTemplateBindingData->m_pTemplatedParentWeakRef = xref::get_weakref(parent);
}

For which platform

No response

Anything else we need to know?

No response

@MartinZikmund MartinZikmund added kind/enhancement New feature or request triage/untriaged Indicates an issue requires triaging or verification difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. project/navigation-lifecycle 🧬 Categorizes an issue or PR as relevant to the navigation and lifecycle (NavigationView, AppBar, ...) area/skia/stability ✏️ area/skia/lifecycle ✏️ difficulty/medium 🤔 Categorizes an issue for which the difficulty level is reachable with a good understanding of WinUI kind/breaking-change 💥 Categorizes an issue or PR as requiring a breaking change to be fixed. and removed triage/untriaged Indicates an issue requires triaging or verification difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. labels Mar 5, 2024
MartinZikmund added a commit that referenced this issue Mar 5, 2024
MartinZikmund added a commit that referenced this issue Mar 5, 2024
MartinZikmund added a commit that referenced this issue Mar 6, 2024
MartinZikmund added a commit that referenced this issue Mar 6, 2024
@jeromelaban
Copy link
Member

This is a duplicate of #1621

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/skia/lifecycle ✏️ area/skia/stability ✏️ difficulty/medium 🤔 Categorizes an issue for which the difficulty level is reachable with a good understanding of WinUI kind/breaking-change 💥 Categorizes an issue or PR as requiring a breaking change to be fixed. kind/enhancement New feature or request project/navigation-lifecycle 🧬 Categorizes an issue or PR as relevant to the navigation and lifecycle (NavigationView, AppBar, ...)
Projects
None yet
Development

No branches or pull requests

2 participants