ZanAlex
Topic Author
Posts: 66
Joined: 16 Jan 2015, 17:46

AttachedProperty in Noesis?

28 Sep 2015, 19:46

Hi everyone,

I have created a RegularGrid control, which is basically a Grid with a fixed number of columns and rows, all having a given dimension, all separated by a given padding. It doesn't really add any feature, but it just provides a cleaner initialization for what I intend to do (I can get rid of the whole ColumnDefinitions/RowDefinitions thingy).

The way I did it is to double the number of rows and columns. Rather than having just a column for instance, I'd have two: one for the content itself and one for the space between the first content and the next one.

What I'd like to do now is to override the attached property of Grid, so that I can set a content inside the grid, without taking into account the fact that I've doubled the number of rows and columns. Since Grid::SetColumn and Grid::SetRow are not virtual, I can't override them.

How can I achieve that? I've heard about attached properties, but I don't think that's exactly what I need. What I do is basically wrapping the calls to SetColumn/SetRow. Is there a way to do that in Xaml?

Many thanks,
Alexandre.
 
User avatar
sfernandez
Site Admin
Posts: 2997
Joined: 22 Dec 2011, 19:20

Re: AttachedProperty in Noesis?

30 Sep 2015, 13:20

I think you need to expose your own properties for the FixedGrid, and internally set the properties of the Grid:
class FixedGrid: public Grid
{
public:
  static const DependencyProperty* ColumnProperty;
  static const DependencyProperty* RowProperty;
  //...
private:
  static void OnColumnChanged(BaseComponent* sender, const DependencyPropertyChangedEventArgs& e)
  {
    DependencyObject* d = NsStaticCast<DependencyObject*>(sender);
    NsUInt32 column =  *static_cast<const NsUInt32*>(e.newValue); // FixedGrid.Column position
    Grid::SetColumn(d, column * 2); // set the real Grid.Column position for the element
  }
  //...
}; 
<FixedGrid Columns="3" Rows="2">
  <Rectangle FixedGrid.Column="2"/>
</FixedGrid> 
 
ZanAlex
Topic Author
Posts: 66
Joined: 16 Jan 2015, 17:46

Re: AttachedProperty in Noesis?

30 Sep 2015, 14:03

So there won't be any conflict with Grid::ColumnProperty for instance?
Also, about the declaration itself, it is exactly the same as a regulary property, isn't it?

Thank you very much!
 
User avatar
sfernandez
Site Admin
Posts: 2997
Joined: 22 Dec 2011, 19:20

Re: AttachedProperty in Noesis?

30 Sep 2015, 16:39

As attached properties are specified along with the class that defines them, it shouldn't be any conflict.

And yes, declaration is the same as any normal property, but attached properties normally have PropertyChangedCallback. This way declaring type can manage property changes in one place.
NS_IMPLEMENT_REFLECTION(FixedGrid)
{
  NsMeta<TypeId>("FixedGrid");

  Ptr<UIElementData> data = NsMeta<UIElementData>(TypeOf<SelfClass>());
  data->RegisterProperty<NsUInt32>(ColumnProperty, "Column",
    FrameworkPropertyMetadata::Create(NsUInt32(0), MakeDelegate(&FixedGrid::OnColumnChanged)));
  //...
} 
 
ZanAlex
Topic Author
Posts: 66
Joined: 16 Jan 2015, 17:46

Re: AttachedProperty in Noesis?

03 Nov 2015, 15:18

Hello,

Sorry for the late answer. I finally took time to check out that solution.

Here's my header file:
class SectorManager : public Noesis::Gui::Canvas
{
    public:
        static const Noesis::Gui::DependencyProperty* XProperty;
        static const Noesis::Gui::DependencyProperty* YProperty;

    private:
        static void onXChanged(Noesis::Core::BaseComponent* sender, 
                                           const Noesis::Gui::DependencyPropertyChangedEventArgs& args);
        static void onYChanged(Noesis::Core::BaseComponent* sender,
                                           const Noesis::Gui::DependencyPropertyChangedEventArgs& args);

    private:
        NS_IMPLEMENT_INLINE_REFLECTION(SectorManager, Noesis::Gui::Canvas)
        {
            NsMeta<Noesis::Core::TypeId>("SectorManager");

            Noesis::Core::Ptr<Noesis::Gui::UIElementData> data = NsMeta<Noesis::Gui::UIElementData>(Noesis::Core::TypeOf<SelfClass>());

            data->RegisterProperty<NsFloat32>(XProperty, "X",
                Noesis::Gui::FrameworkPropertyMetadata::Create(NsFloat32(0), Noesis::Core::MakeDelegate(&SectorManager::onXChanged)));
            data->RegisterProperty<NsFloat32>(YProperty, "Y",
                    Noesis::Gui::FrameworkPropertyMetadata::Create(NsFloat32(0), Noesis::Core::MakeDelegate(&SectorManager::onYChanged)));
        }
};
The .cpp file contains the declaration of both properties and the body of onXChanged and onYChanged.

My Xaml is as simple as that:
<SectorManager>
      <Rectangle Height="50" Width="70" SectorManager.X="0.5" SectorManager.Y="0.5" Fill="Red"/>
</SectorManager>
However, neither of my callback is called when executing that code. What am I missing?

Many thanks,
Alexandre.
 
User avatar
sfernandez
Site Admin
Posts: 2997
Joined: 22 Dec 2011, 19:20

Re: AttachedProperty in Noesis?

10 Nov 2015, 10:16

Hi Alex,

That was a tricky one , it was a problem of function overload :)

It turns out that your property changed callbacks aren't following the correct signature, so compiler is calling the wrong Create version. The sender parameter must be of type DependencyObject, yours was a BaseComponent:
static void onXChanged(Noesis::Gui::DependencyObject* sender,
    const Noesis::Gui::DependencyPropertyChangedEventArgs& args);
static void onYChanged(Noesis::Gui::DependencyObject* sender,
    const Noesis::Gui::DependencyPropertyChangedEventArgs& args);

Who is online

Users browsing this forum: Ahrefs [Bot] and 40 guests