0

I want to create a DependencyProperty in an extension class for FrameworkElement, and bind a xaml property to it.

The idea comes from the source code of the Windows Community Toolkit : https://github.com/windows-toolkit/WindowsCommunityToolkit

They are using extensions to add a DependencyProperty to FrameworkElement, in FrameworkElementExtensions.ActualSize.cs file.

I can use their extension without any problem, however when I try to do the same thing myself, I get a Windows.UI.Xaml.Markup.XamlParseException: 'XAML parsing failed.'

I even tried copy/pasting their extension class and the problem persists.

My project is a UWP project.


Here is some simple code to test it out:


    <UserControl
        xmlns:myExtensions="using:MyProject.Extensions"
        xmlns:toolkitExtensions="using:Microsoft.Toolkit.Uwp.UI.Extensions"
        >
        <Grid>
            <Grid x:Name="TestElementName"
                  myExtensions:FrameworkElementExtensions.CustomProperty="0.5"
                  toolkitExtensions:FrameworkElementExtensions.EnableActualSizeBinding="true"
                  />

            <Grid Width="{Binding ElementName=TestElementName, Path=(toolkitExtensions:FrameworkElementExtensions.ActualWidth)}"
                  Height="{Binding ElementName=TestElementName, Path=(myExtensions:FrameworkElementExtensions.ActualHeight)}"
                  Opacity="{Binding ElementName=TestElementName, Path=(myExtensions:FrameworkElementExtensions.CustomProperty)}"
                  />
        </Grid>
    </UserControl>


    namespace MyProject.Extensions
    {
        public static partial class FrameworkElementExtensions
        {
            public static readonly DependencyProperty ActualHeightProperty = DependencyProperty.RegisterAttached("ActualHeight", typeof(double), typeof(FrameworkElement), new PropertyMetadata(double.NaN));

            public static double GetActualHeight(FrameworkElement obj)
            {
                return (double)obj.GetValue(ActualHeightProperty);
            }

            public static void SetActualHeight(FrameworkElement obj, double value)
            {
                obj.SetValue(ActualHeightProperty, value);
            }

            public static readonly DependencyProperty CustomPropertyProperty = DependencyProperty.RegisterAttached("CustomProperty", typeof(double), typeof(FrameworkElement), new PropertyMetadata(1.0));

            public static double GetCustomProperty(FrameworkElement obj)
            {
                return (double)obj.GetValue(CustomPropertyProperty);
            }

            public static void SetCustomProperty(FrameworkElement obj, double value)
            {
                obj.SetValue(CustomPropertyProperty, value);
            }
        }
    }

The ActualHeight property is copy/pasted from Windows Community Toolkit

The CustomProperty property is mine

Assignment in the 1st Grid works correctly, but bindings to both Height and Opacity in the 2nd Grid throw an exception.

I don't see how it can work when used from the Community Toolkit namespace and not from mine.


Details from the exception:

Type: Windows.UI.Xaml.Markup.XamlParseException

Message: XAML parsing failed.

Stacktrace:

   at Windows.UI.Xaml.Application.LoadComponent(Object component, Uri resourceLocator, ComponentResourceLocation componentResourceLocation)
   at MyProject.Controls.MyControl.InitializeComponent()
   at MyProject.Controls.MyControl..ctor()
   at MyProject.MyProject_XamlTypeInfo.XamlTypeInfoProvider.Activate_271_MyControl()
   at MyProject.MyProject_XamlTypeInfo.XamlUserType.ActivateInstance()

InnerException is null.


Can anyone help me with this?

Thank you.

Down
  • 36
  • 5
  • "*throw an exception*" -- what exception? What's the message and stack trace? – canton7 Apr 17 '19 at 12:47
  • @canton7 I added details for the exception – Down Apr 17 '19 at 12:54
  • And the InnerExceptions? – canton7 Apr 17 '19 at 12:56
  • At the moment, the obvious thing that's wrong is that your `UserControl` has two children, when it only supports one. However, without the full exception information (including the InnerExeptions, and their InnerExceptions, which will say how exactly the XAML parsing failed), it's impossible to say for sure. – canton7 Apr 17 '19 at 12:57
  • @canton7 The children problem is due to me wanting to simplify the sample for the post. It has been fixed. The innerException is null. @mm8 I tried it and the problem persists. The thing is, everything works properly if I only use the properties from `toolkitExtensions` – Down Apr 17 '19 at 13:09
  • *Please* make sure that the code you post can actually reproduce the error you're seeing. For all we know, you inadvertently fixed the problem when creating a simplified sample, and there's now no error for us to find! – canton7 Apr 17 '19 at 13:14
  • Can you confirm that the code that's now in your question actually reproduces the exception you posted? – canton7 Apr 17 '19 at 13:17
  • @canton7 I tried a simple new project with only the code from my post, and the exception was not thrown. You were right, I fixed the problem when creating a simplified sample. Well done and thank you for pointing this out, and I will be very carefull about this in the future. – Down Apr 17 '19 at 14:01

1 Answers1

1

I fixed it thanks to the insight of canton7.

The problem is from the DependencyProperty declaration.

Replace

    public static readonly DependencyProperty CustomPropertyProperty = DependencyProperty.RegisterAttached("CustomProperty", typeof(double), typeof(FrameworkElement), new PropertyMetadata(1.0));

with

    public static readonly DependencyProperty CustomPropertyProperty = DependencyProperty.RegisterAttached("CustomProperty", typeof(double), typeof(FrameworkElementExtensions), new PropertyMetadata(1.0));

The key here is the ownerType parameter from DependencyProperty.RegisterAttached(). It needs to be the extension type, and not the extended one.

Down
  • 36
  • 5