UICollection DependenciesProperty
I have a particular custom Control that defines a Collection DependencyProperty:
This is used to specify some UIElements that get rendered in a Panel in the Control's Template. There is a single instance that is specified in a DataTemplate:
This works as expected as long the Template is not used multiple times, otherwise, unique control instances are created, but they all point to the same collection, and so the items are only rendered by one instance.
I have tried assigning a new empty collection to the Property in the Control's Constructor, which makes the collections unique, but then the items are never added to them.
Is this just an inherent limitation or is there something I am missing?
Code: Select all
pTypeData->RegisterProperty<Noesis::Ptr<Noesis::UICollection<Noesis::BaseComponent>>>(
s_itemsProperty,
"items",
Noesis::FrameworkPropertyMetadata::Create(Noesis::Ptr<Noesis::UICollection<Noesis::BaseComponent>>(),
Noesis::FrameworkPropertyMetadataOptions_None)
);
Code: Select all
<DataTemplate>
...
<CustomControl>
<CustomControl.items>
<Rectangle/>
<Ellipse/>
...
<CustomControl.items>
</CustomControl>
</DataTemplate>
I have tried assigning a new empty collection to the Property in the Control's Constructor, which makes the collections unique, but then the items are never added to them.
Is this just an inherent limitation or is there something I am missing?
-
-
sfernandez
Site Admin
- Posts: 3363
- Joined:
Re: UICollection DependenciesProperty
When your CustomControl is placed inside a template and then it gets applied, it will create a new instance of your CustomControl by cloning it, and copying all the dependency property values. This means that all instantiations of the template will share the same "items" UICollection.
To avoid this I suggest you define your "items" property as a reflection only property:
And then when your custom control gets cloned by the template, you also clone the UI elements in your "items" collection:
Could you try that?
To avoid this I suggest you define your "items" property as a reflection only property:
Code: Select all
class CustomControl: public Control
{
public:
CustomControl();
UICollection<FrameworkElement>* get_items() const;
protected:
void CloneOverride(FrameworkElement* clone, FrameworkTemplate* template_) const override;
private:
Ptr<UICollection<FrameworkElement>> m_items;
NS_DECLARE_REFLECTION(CustomControl, Control)
};
Code: Select all
CustomControl::CustomControl(): m_items(*new UICollection<FrameworkElement>()) { ConnectNode(m_items, this); }
UICollection<FrameworkElement>* CustomControl::get_items() const { return m_items; }
NS_IMPLEMENT_REFLECTION(CustomControl, "MyProject.CustomControl")
{
NsMeta<ContentPropertyMetaData>("items");
NsProp("items", &CustomControl::get_items);
}Code: Select all
void CustomControl::CloneOverride(FrameworkElement* clone, FrameworkTemplate* template_) const
{
CustomControl* custom = (CustomControl*)clone;
FrameworkElement* templatedParent = custom->GetTemplatedParent();
for (int i = 0; i < m_items->Count(); ++i)
{
FrameworkElement* item = m_items->Get(i);
custom->m_items->Add(item->Clone(custom, templatedParent, template_));
}
}Re: UICollection DependenciesProperty
This is insightful, thanks! I won't be able to try it out any time soon, but I'll take your word for it.
Who is online
Users browsing this forum: No registered users and 6 guests