User avatar
Gazoo
Topic Author
Posts: 36
Joined: 14 Sep 2022, 10:00
Contact:

Re: Dynamically adding a new widget in C++ code, and then using FindName() to get it

20 Oct 2022, 12:02

I cannot overstate my appreciation for your on-going assistance. Thanks to your help maherne, I've managed to get the registration code to trigger. I also managed to place ElementRegistry in its own namespace (Ozmodiar) with the following change:
NS_IMPLEMENT_REFLECTION( ElementRegistry, "Ozmodiar.ElementRegistry" )
I've added the following cs dummy file:
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Markup;
using Microsoft.Xaml.Behaviors;

namespace Ozmodiar
{

    class ElementRegistry : DependencyObject
    {

        #region IsRegistered property
        public static readonly DependencyProperty IsRegisteredProperty = DependencyProperty.Register(
            "IsRegistered", typeof(bool), typeof(ElementRegistry), new PropertyMetadata(false));

        public bool IsRegistered
        {
            get { return (bool)GetValue(IsRegisteredProperty); }
            set { SetValue(IsRegisteredProperty, value); }
        }
        #endregion

    }

}
While the Ozmodiar namespace seems to be accepted, I'm still getting the following errors preventing the xaml from being rendered in the blend designer:
Error	XLS0415	The attachable property 'IsRegistered' was not found in type 'ElementRegistry'.	noesis_sandbox_gui
Error	XDG0044	The local property "IsRegistered" can only be applied to types that are derived from "ElementRegistry".
I've attached the namespace to the canvas tag, and reference the dependency property as follows:
...
xmlns:local2="clr-namespace:Ozmodiar"
...
<Button Height="45" Width="88" Canvas.Left="274" Canvas.Top="50" Content="Ajajaja" local2:ElementRegistry.IsRegistered="True" />
It seems I'm overlooking something, but I'm not clear as to what's missing...?

Gazoo
 
User avatar
maherne
Site Admin
Posts: 25
Joined: 01 Jul 2022, 10:10

Re: Dynamically adding a new widget in C++ code, and then using FindName() to get it

20 Oct 2022, 14:00

I'm happy to help in any way I can, thanks!

In WPF/C# you need to use DependencyProperty.RegisterAttached to register attached properties, this should fix your Blend error. You can find documentation and examples here: https://learn.microsoft.com/en-us/dotne ... esktop-7.0. Note that these attached properties use static properties also.
 
User avatar
Gazoo
Topic Author
Posts: 36
Joined: 14 Sep 2022, 10:00
Contact:

Re: Dynamically adding a new widget in C++ code, and then using FindName() to get it

21 Oct 2022, 11:13

Thanks for the continued assistance! I managed to get the attached property properly recognized in Blend (C#). For others reading along, the example looks as follows:
namespace Ozmodiar
{

    class ElementRegistry
    {
        // Register an attached dependency property with the specified
        // property name, property type, owner type, and property metadata.
        public static readonly DependencyProperty IsRegisteredProperty =
            DependencyProperty.RegisterAttached(
          "IsRegistered",
          typeof(bool),
          typeof(ElementRegistry)//,
          //new FrameworkPropertyMetadata(defaultValue: false,
          //    flags: FrameworkPropertyMetadataOptions.AffectsRender)
        );

        // Declare a get accessor method.
        public static bool GetIsRegistered(UIElement target) =>
            (bool)target.GetValue(IsRegisteredProperty);

        // Declare a set accessor method.
        public static void SetIsRegistered(UIElement target, bool value) =>
            target.SetValue(IsRegisteredProperty, value);

    }

}
One thing which I'm still wondering about, is namespace placement.

Noesis allows the ElementRegistry to be declared in a common or unique namespace via either of the following macro calls:
	NS_IMPLEMENT_REFLECTION( ElementRegistry, "Ozmodiar.ElementRegistry" )
	NS_IMPLEMENT_REFLECTION( ElementRegistry )
On the C# side however, the only way I've managed to place ElementRegistry in the common namespace, is as follows:
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "Ozmodiar")]

namespace Ozmodiar
{
...
It is ultimately probably best to maintain custom elements in a new namespace, but I'm open to any suggestions to defining ElementRegistry in the common namespace. For example, is there a way to do it purely in the xaml file?

Cheers,
Gazoo
 
User avatar
maherne
Site Admin
Posts: 25
Joined: 01 Jul 2022, 10:10

Re: Dynamically adding a new widget in C++ code, and then using FindName() to get it

21 Oct 2022, 11:47

It is best to maintain custom elements in a new namespace as this is the expected behaviour for WPF/Blend. I do not believe there is a way to include types or namespaces in the default namespace using XAML.

Thanks for sharing your example!
 
User avatar
Gazoo
Topic Author
Posts: 36
Joined: 14 Sep 2022, 10:00
Contact:

Re: Dynamically adding a new widget in C++ code, and then using FindName() to get it

22 Oct 2022, 05:13

I try my best to 'pay it forward' when I get help. I.e. I may as well share the portions of work/code I manage to figure out so other readers can gain from it.

As for including something in the default namespace, I just wanted to emphasize that the approach I list above, which involves this line of code in the C# file:
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "Ozmodiar")]
does appear to accomplish this.

As you noted though, it's likely a wise move to always use a newly declared namespace as it's the only way to avoid accidentally conflicting with something already defined in the namespace.

Cheers,
Gazoo

Who is online

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