Page 1 of 1
AttachedProperty in Noesis?
Posted: 28 Sep 2015, 19:46
by ZanAlex
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.
Re: AttachedProperty in Noesis?
Posted: 30 Sep 2015, 13:20
by sfernandez
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>
Re: AttachedProperty in Noesis?
Posted: 30 Sep 2015, 14:03
by ZanAlex
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!
Re: AttachedProperty in Noesis?
Posted: 30 Sep 2015, 16:39
by sfernandez
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)));
//...
}
Re: AttachedProperty in Noesis?
Posted: 03 Nov 2015, 15:18
by ZanAlex
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.
Re: AttachedProperty in Noesis?
Posted: 10 Nov 2015, 10:16
by sfernandez
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);