Page 1 of 1

UICollection DependenciesProperty

Posted: 27 Mar 2026, 15:00
by JTT
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?

Re: UICollection DependenciesProperty

Posted: 01 Apr 2026, 13:25
by sfernandez
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?

Re: UICollection DependenciesProperty

Posted: 02 Apr 2026, 11:43
by JTT
This is insightful, thanks! I won't be able to try it out any time soon, but I'll take your word for it.