Assertion when removing an object from its parent's children collection
I have a view with some basic controls. I want to have 2 versions of it so I can do a staged rollout with A/B testing. Version A throws a bunch of controls in a stack panel, and Version B organizes the same set of controls into a slightly different tree structure. My XAML file defines all of the controls using Version A and stubs out some empty containers that Version B uses. Once my page is loaded, I run some code which determines if we are showing A or B. For A, it will remove the Version B stub containers and for B it will remove the controls from the Version A stack panel and add them to the Version B containers (then remove the Version A stack panel entirely). I like this approach because I only need to define the controls 1 time in XAML and can put them in correct place + remove the excess containers for the other version at run-time. Below is the function I'm using for these 2 operations. The problem is that if I call TryFindAndChangeParent with a nullptr newParent (i.e., without adding it back), I get the following assertion failure when the function returns and the control (now with a ref-count of 0) is disposed of:
[NOESIS/E] Assertion failed: mTemplatedParent == 0, at FrameworkElement.cpp(1575)
FWIW all the controls I'm passing to these functions are inside a template and the code is running during the "Loaded" event for that ControlTemplate. I am aware that I could also use collapsed visibility to "remove" an item, but since these controls are meant for an entirely different version of the UI screen, I think it makes more sense to actually remove them.
Also, the C# equivalent of this code works without issue if I run it in Microsoft Blend.
Here is the callstack:
[NOESIS/E] Assertion failed: mTemplatedParent == 0, at FrameworkElement.cpp(1575)
Code: Select all
static bool TryFindAndChangeParent(FrameworkElement * root, const char * name, Panel * newParent)
{
if (!root)
return false;
Ptr<FrameworkElement> found(DynamicCast<FrameworkElement*>(root->FindName(name)));
if (!found)
return false;
Ptr<Panel> parent(DynamicCast<Panel*>(found->GetParent()));
if (!parent)
return false;
bool success = parent->GetChildren()->Remove(found);
if (success && newParent)
{
newParent->GetChildren()->Add(found);
}
return success;
}
static bool TryFindAndRemove(FrameworkElement * root, const char * name)
{
return TryFindAndChangeParent(root, name, nullptr);
}
Also, the C# equivalent of this code works without issue if I run it in Microsoft Blend.
Here is the callstack:
-
sfernandez
Site Admin
- Posts: 2983
- Joined:
Re: Assertion when removing an object from its parent's children collection
Thanks for reporting this. Our code was not designed to remove elements manually from the template tree, only for applying and removing the whole template. Could you please add a ticket in our bugtracker and we will solve it for the next release?
In the meantime you can just call found->SetTemplatedParent(0,0) to avoid the assert.
In the meantime you can just call found->SetTemplatedParent(0,0) to avoid the assert.
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 24 guests