daniilch
Topic Author
Posts: 11
Joined: 02 Mar 2022, 10:05

DependencyProperty.AddOwner registers multiple callbacks for single type

08 Dec 2022, 11:57

Hello. I think, I found a bug in DependencyProperty.AddOwner implementation.

Lets create two UserControls: UserControlA and UserControlB.
UserControlA defines a dependency property Value with a default value and a change callback.
UserControlB reuses this property with AddOwner, redefining its own change callback.

Code:
public partial class UserControlA : UserControl
{
    ... ctor, InitializeComponent, CLR property definition omitted ... 

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(int), typeof(UserControlA), new PropertyMetadata(5, OnValueChanged));

    private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"UserControlA: d is {d.GetType().Name}: Value changed to {e.NewValue}");
    }
}

public partial class UserControlB : UserControl
{
    ... ctor, InitializeComponent, CLR property definition omitted ... 

    public static readonly DependencyProperty ValueProperty =
        UserControlA.ValueProperty.AddOwner(typeof(UserControlB), new PropertyMetadata(OnValueChanged));

    private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"UserControlB: d is {d.GetType().Name}, Value changed to {e.NewValue}");
    }
}
Lets use these controls somewhere in a view in the following way:
<StackPanel Orientation="Vertical">
    <vcviews:UserControlA Value="8" />
    <vcviews:UserControlB Value="10" />
</StackPanel>
Compiling and runnig this code in WPF we get the following messages in output window:
UserControlA: d is UserControlA: Value changed to 8
UserControlB: d is UserControlB, Value changed to 10
All is fine, both controls got their change notifications.

But in Noesis this code fails with exception:
ArgumentException: Invalid default value type for dependency property 'Brio.MRS.ViewCore.Views.UserControlB.Value'
Noesis.DependencyProperty.ValidateDefaultValue (System.String name, System.Type type, System.Type owner, System.Object value) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/API/Proxies/DependencyPropertyExtend.cs:180)
Noesis.DependencyProperty.AddOwner (System.Type ownerType, Noesis.PropertyMetadata metadata) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/API/Proxies/DependencyPropertyExtend.cs:42)
Brio.MRS.ViewCore.Views.UserControlB..cctor () (at Assets/Modules/ViewCore/Views/UserControlB.xaml.cs:12)
Rethrow as TypeInitializationException: The type initializer for 'Brio.MRS.ViewCore.Views.UserControlB' threw an exception.
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (System.RuntimeTypeHandle type) (at <695d1cc93cca45069c528c15c9fdd749>:0)
Noesis.Extend.RunClassConstructor (System.Type type) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/API/Core/Extend.cs:1765)
Noesis.Extend.RegisterDependencyProperties (System.Type type) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/API/Core/Extend.cs:1730)
Noesis.Extend.RegisterNativeType (System.Type type, System.Boolean registerDP) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/API/Core/Extend.cs:1374)
Noesis.Extend.RegisterNativeType (System.Type type) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/API/Core/Extend.cs:1221)
Noesis.Extend.RegisterType (System.String typeName) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/API/Core/Extend.cs:1877)
UnityEngine.Debug:LogException(Exception)
NoesisUnity:OnUnhandledException(Exception) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/NoesisUnity.cs:374)
Noesis.Error:UnhandledException(Exception) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/API/Core/Error.cs:18)
Noesis.Extend:RegisterType(String) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/API/Core/Extend.cs:1882)
Noesis.GUI:Noesis_LoadComponent(HandleRef, String)
Noesis.GUI:LoadComponent(Object, String) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/API/Core/NoesisGUI.cs:322)
NoesisUnity:LoadComponent(Object, String) (at Library/PackageCache/com.noesis.noesisgui@36e5d70d8b/Runtime/NoesisUnity.cs:270)
Brio.MRS.BimViewer.Views.BimViewerView:InitializeComponent() (at Assets/Modules/BimViewer/Views/BimViewerView.xaml.cs:20)
Brio.MRS.BimViewer.Views.BimViewerView:.ctor() (at Assets/Modules/BimViewer/Views/BimViewerView.xaml.cs:14)
...
Adding a default value to UserControlB property definition:
public partial class UserControlB : UserControl
{
    public static readonly DependencyProperty ValueProperty =
        UserControlA.ValueProperty.AddOwner(typeof(UserControlB), new PropertyMetadata(7, OnValueChanged));
                                                                               //------^
    ...
}
After that exception does not occure, but there's another problem: UserControlA receives property change callback from UserControlB:
UserControlA: d is UserControlA: Value changed to 8
UserControlA: d is UserControlB: Value changed to 10    <== !    
UserControlB: d is UserControlB, Value changed to 10
Of course, there's no actual need to use AddOwner in this code (and in my code too, to be fair), but this is a behaviour mismatch between WPF and Noesis, and you guys seem to be willing to fix those things :) Thanks in advance.
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: DependencyProperty.AddOwner registers multiple callbacks for single type

12 Dec 2022, 18:45

Hi,

There are clearly a couple of problems here, first we should allow not specifying the default value when doing AddOwner, and then the multiple callbacks error. Could you please report them in our bugtracker? we will solve them as soon as possible.
 
daniilch
Topic Author
Posts: 11
Joined: 02 Mar 2022, 10:05

Re: DependencyProperty.AddOwner registers multiple callbacks for single type

13 Dec 2022, 06:59

Sure, I filed a bug: https://www.noesisengine.com/bugs/view.php?id=2476

By the way if I find a bug is it better to create a forum post beforehand, or maybe I may create an issue in bugtracker directly?
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: DependencyProperty.AddOwner registers multiple callbacks for single type

16 Dec 2022, 18:24

Thanks for the report.

For crashes it is better to open a ticket in the bugtracker with a crash dump if possible, and reproduction steps.
But if you're unsure if something that is happening to you is a missing feature, usage error or something wrong in Noesis, don't hesitate to ask in the forums.

Who is online

Users browsing this forum: No registered users and 7 guests