Attached Property Changed Handler
Hello,
1.- I have a custom-control in WPF where I can subscribe to the change notification of an attached property with this:
But I couldn't find something similar, is there a way to do this with Noesis?
2.-While trying to use FocusManager.IsFocusScope in a xaml file, the resource build tool does not recognize it,
is there a namespace I need to add?
3.- I'm creating an user control is the OnPostInit method a good place to find some controls?
also do I need to unsubscribe?, I'm asking this because of the trello https://trello.com/c/k7pREwVK/29-435-ci ... t-handlers
and if so, what would be the best overriding member method to do it ?
4.- this xaml is not setting the canvas left and top is not working
this is the type of SourcePoint
do you know why?
5.- Where can I see the binding errors ?
6.- how can I freeze a resource with noesis (I was told that is better to freeze the brushes for performance), in wpf I used to do this
7.- it seems that
is not working in controls
Thanks!.
1.- I have a custom-control in WPF where I can subscribe to the change notification of an attached property with this:
Code: Select all
DependencyPropertyDescriptor.FromProperty(Canvas.LeftProperty, typeof (MyCustomControl)).AddValueChanged(Mydelegate);
2.-While trying to use FocusManager.IsFocusScope in a xaml file, the resource build tool does not recognize it,
is there a namespace I need to add?
3.- I'm creating an user control is the OnPostInit method a good place to find some controls?
Code: Select all
void DiagramEditor::OnPostInit()
{
ParentClass::OnPostInit();
m_canvas = FindName<Canvas>("TheCanvas");
m_canvas->PreviewMouseWheel() += MakeDelegate(this,&DiagramEditor::OnEditorZoom);
}
and if so, what would be the best overriding member method to do it ?
4.- this xaml is not setting the canvas left and top is not working
Code: Select all
<Ellipse Fill="{StaticResource ConnectorColorBrush}" Height="10" Width="10" Name="Circle"
Canvas.Left="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SourcePoint.X}"
Canvas.Top="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SourcePoint.Y}">
Code: Select all
struct Point : Drawing::Point
{
NS_IMPLEMENT_INLINE_REFLECTION(Point, Drawing::Point)
{
NsMeta<Core::TypeId>("Editor.Point");
NsProp("X", &Point::GetX, &Point::SetX);
NsProp("Y", &Point::GetY, &Point::SetY);
}
}
5.- Where can I see the binding errors ?
6.- how can I freeze a resource with noesis (I was told that is better to freeze the brushes for performance), in wpf I used to do this
Code: Select all
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:po="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:editor="clr-namespace:Editor">
<SolidColorBrush x:Key="ConnectorColorBrush" Color="#888" po:Freeze="True" />
Code: Select all
void OnPreviewMouseDoubleClick(const Gui::MouseButtonEventArgs& e) override;

Thanks!.
-
-
sfernandez
Site Admin
- Posts: 3275
- Joined:
Re: Attached Property Changed Handler
Hi,
1. We don't have DependencyPropertyDescriptor implemented, could you please create a ticket in our bugtracker about this?
Right now the alternative in NoesisGUI are:
- If you want to know when a specific dependency property changes in you control, you can override the OnPropertyChanged method:
- If you want to subscribe to dependency property changes in a particular instance of your control from another class, you can use the public delegate DependencyPropertyChanged:
2. FocusManager is not implemented in NoesisGUI, we have plans to include it in 1.3 version.
Now only Keyboard focus is available and you can access it from any UIElement instance:
3. The OnPostInit is a perfect place to find other controls, although we want to substitute that method in a future version with the WPF equivalent OnInitialized, that corresponds to the Initialized event. Another thing we have in mind is to generate automatically code that solves x:Name references in a xaml file to the appropriate member in the code-behind class, so you don't have to worry about doing the FindNames yourself.
The problem described in that Trello card refers to the Unity version, because C# keeps strong references when a delegate is attached to an event. In C++, our delegate system uses raw pointers to avoid the circular references. You don't need to unsubscribe if your instance (DiagramEditor instance) will be destroyed after the event holder (Canvas instance). If you think that event holder will raise the event after your instance is detroyed, you need to unsubscribe (usually in your class destructor) to avoid a crash.
4. This seems a bug, could you please report it in our bugtracker?
Anyway, this kind of binding won't be updated if SourcePoint values change as tthe struct is not a DependencyObject and cannot be a INotifyPropertyChanged object. I recommend to expose SourcePointX and SourcePointY as individual properties in your templated parent control.
5. In the Gui.XamlPlayer.ini you can specify a logfile, and enable binding warnings:
The generated log file is not a plain text file (uses an internal format for our debug tools), but can be opened with any text editor and you will see there all the messages, including information about any Binding that fails to solve and the reason.
6. Resources can't be frozen in XAML directly, you have to do it in code. Could you please add a ticket about the Freeze xaml option in our bugtracker, this seems an interesting feature to implement.
7. What do you mean? Is the virtual function not being called?
Are you injecting the double click to the IRenderer?
1. We don't have DependencyPropertyDescriptor implemented, could you please create a ticket in our bugtracker about this?
Right now the alternative in NoesisGUI are:
- If you want to know when a specific dependency property changes in you control, you can override the OnPropertyChanged method:
Code: Select all
NsBool MyCustomControl::OnPropertyChanged(const DependencyPropertyChangedEventArgs& args)
{
ParentClass::OnPropertyChanged(args);
if (args.prop == Canvas::LeftProperty)
{
// ...
}
return false;
}
Code: Select all
MyCustomControl* control = ...;
control->DependencyPropertyChanged() += MakeDelegate(this, &AnotherClass::OnCustomControlLeftChanged);
...
void AnotherClass::OnCustomControlLeftChanged(BaseComponent* sender,
const DependencyPropertyChangedEventArgs& args)
{
if (args.prop == Canvas::LeftProperty)
{
MyCustomControl* control = NsStaticCast<MyCustomControl*>(sender);
...
}
}
Now only Keyboard focus is available and you can access it from any UIElement instance:
Code: Select all
UIElement* element = ...;
Keyboard* keyboard = element->GetKeyboard();
UIElement* focusedElement = keyboard->GetFocused();
keyboard->Focus(anotherElement);
The problem described in that Trello card refers to the Unity version, because C# keeps strong references when a delegate is attached to an event. In C++, our delegate system uses raw pointers to avoid the circular references. You don't need to unsubscribe if your instance (DiagramEditor instance) will be destroyed after the event holder (Canvas instance). If you think that event holder will raise the event after your instance is detroyed, you need to unsubscribe (usually in your class destructor) to avoid a crash.
4. This seems a bug, could you please report it in our bugtracker?
Anyway, this kind of binding won't be updated if SourcePoint values change as tthe struct is not a DependencyObject and cannot be a INotifyPropertyChanged object. I recommend to expose SourcePointX and SourcePointY as individual properties in your templated parent control.
5. In the Gui.XamlPlayer.ini you can specify a logfile, and enable binding warnings:
Code: Select all
[Core.Logger]
Filename = "noesis.log"
[Gui.Binding]
LogWarnings = true
6. Resources can't be frozen in XAML directly, you have to do it in code. Could you please add a ticket about the Freeze xaml option in our bugtracker, this seems an interesting feature to implement.
7. What do you mean? Is the virtual function not being called?
Are you injecting the double click to the IRenderer?
Code: Select all
IRenderer* uiRenderer = ...;
uiRenderer->MouseDoubleClick(mousePos.x, mousePos.y, MouseButton_Left);
Re: Attached Property Changed Handler
Hi, thanks for your responses
The bugtracker page keeps rejecting my credentials, is there something else I need to do to gain access?
The bugtracker page keeps rejecting my credentials, is there something else I need to do to gain access?
Re: Attached Property Changed Handler
The bug tracker and the forum accounts are not linked. You need to create a new bug tracker account.Hi, thanks for your responses
The bugtracker page keeps rejecting my credentials, is there something else I need to do to gain access?
Maybe a good idea to add that info in a sticky topic and on the bug tracker log in page.
Re: Attached Property Changed Handler
Thanks for the suggestion. I will create a sticky post with useful information about reporting a BUG in NoesisGUI, including the account creation detail.
Re: Attached Property Changed Handler
Hi Again!
1.-Is this a correct behaviour :
this method is subscribed to changes of both collections , and my intend was to do a dynamic_cast to determine which of both is the collection that raised the handler, but both return not null
2.- While trying to do this
I get the following error:
do I need to provide a converter?, this type of automatic conversions are common in xaml & wpf.
1.-Is this a correct behaviour :
this method is subscribed to changes of both collections , and my intend was to do a dynamic_cast to determine which of both is the collection that raised the handler, but both return not null
2.- While trying to do this
Code: Select all
<editor:Connector Source="{Binding ElementName=DesignerItem}" TargetPoint="400,400" Text="Jump" />
Code: Select all
Parsing Editor.Connector.TargetPoint (@21,12).
1> '400,400' is not a valid value for property 'Editor.Connector.TargetPoint'
-
-
sfernandez
Site Admin
- Posts: 3275
- Joined:
Re: Attached Property Changed Handler
1. It's not the expected behavior. I confirmed that the ObservableCollection class doesn't have the reflection marks specified, that's why it is returning the base class type (Collection) when doing a dynamic cast. We will solve this for the next version.
Meanwhile you have to subscribe using different methods for each ObservableCollection type.
2. How is TargetPoint type declared? Is inheriting from Noesis::Drawing::Point or is a new type?
If it is a new struct type you need to define a method like this:
And register the converter for that type in your dll:
Meanwhile you have to subscribe using different methods for each ObservableCollection type.
2. How is TargetPoint type declared? Is inheriting from Noesis::Drawing::Point or is a new type?
If it is a new struct type you need to define a method like this:
Code: Select all
static NsBool TryParse(const NsChar* str, TargetPoint& result);
Code: Select all
extern "C" NS_DLL_EXPORT
void NsRegisterReflection(ComponentFactory* factory, NsBool registerComponents)
{
// ...
NS_REGISTER_COMPONENT(Noesis::Core::Converter<Editor::Connector::TargetPoint>)
}
Who is online
Users browsing this forum: Ahrefs [Bot] and 38 guests