JTT
Topic Author
Posts: 7
Joined: 03 Dec 2025, 12:37

UICollection DependenciesProperty

27 Mar 2026, 15:00

I have a particular custom Control that defines a Collection DependencyProperty:
pTypeData->RegisterProperty<Noesis::Ptr<Noesis::UICollection<Noesis::BaseComponent>>>(
    s_itemsProperty,
    "items",
    Noesis::FrameworkPropertyMetadata::Create(Noesis::Ptr<Noesis::UICollection<Noesis::BaseComponent>>(),
    Noesis::FrameworkPropertyMetadataOptions_None)
);
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:
<DataTemplate>
  ...
  <CustomControl>
   <CustomControl.items>
      <Rectangle/>
      <Ellipse/>
      ...
    <CustomControl.items>
  </CustomControl>
</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?
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: UICollection DependenciesProperty

01 Apr 2026, 13:25

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:
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)
};
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);
}
And then when your custom control gets cloned by the template, you also clone the UI elements in your "items" collection:
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_));
  }
}
Could you try that?
 
JTT
Topic Author
Posts: 7
Joined: 03 Dec 2025, 12:37

Re: UICollection DependenciesProperty

02 Apr 2026, 11:43

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