简体   繁体   中英

Using Custom Attached Properties with Base Class and Generics

I wish to use AngelSix's custom attached properties Code in a .NET Framework 4.7.2 class library. However, when I try to add an attached property to an object in a Xaml file, what I get from Intellisense in Visual Studio is local:BaseAttachedProperty`2.value and not the desired attached property like local:IsBusyProperty.Value . When I manually type local:IsBusyProperty.Value , the application crashes with the error message The method or operation is not implemented pointing to the attached property. I understand that the `2 means a generic type, with 2 generic parameters - alluding to the Base Class with two generic parameters:

public abstract class BaseAttachedProperty<Parent, Property>
        where Parent : new(){}

But how do I get the correct attached property, that is, classes that implement the base class with generic parameters and not this cryptic local:BaseAttachedProperty`2.value message?

If I create an Attached Property without inheriting from the BaseAttachedProperty, everything works fine.

A user on a German Forum had the same problem and writes that he could use xmlns: to get the attached properties but this does not work for me!

Here is a sample that AngelSix provided. It will not work for me.

public class IsBusyProperty : BaseAttachedProperty<IsBusyProperty, bool>
{
}

Here is my code which works:

public class IsBusyProperty
    {
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.RegisterAttached("Value", typeof(bool), typeof(IsBusyProperty), new PropertyMetadata(false));
        public static bool GetValue(DependencyObject obj)
        {
            return (bool)obj.GetValue(ValueProperty);
        }
        public static void SetValue(DependencyObject obj, bool value)
        {
            obj.SetValue(ValueProperty, value);
        }
    }

The code is consumed as follows (here my code is not in use):

<Button Content="Login" 
                                    IsDefault="True"
                                    local:BaseAttachedProperty`2.Value="{Binding LoginIsRunning}" <-- Here is the trouble area
                                    Command="{Binding LoginCommand}"
                                    CommandParameter="{Binding ElementName=Page}" 
                                    HorizontalAlignment="Center" />

If the attached property works, the correct code should be

<Button Content="Login" 
                                    IsDefault="True"
                                    local:IsBusyProperty.Value="{Binding LoginIsRunning}"
                                    Command="{Binding LoginCommand}"
                                    CommandParameter="{Binding ElementName=Page}" 
                                    HorizontalAlignment="Center" />

I've never used the code you linked to, but from what I see I think you're misunderstanding how it's meant to be used. Let me bring your attention back to this code you referenced:

public class IsBusyProperty : BaseAttachedProperty<IsBusyProperty, bool>
{
}

That is not an exmaple you're supposed to fill in, that is actually a fully functional attached property that you can use. The reason it's empty is because all the code you need is already in the base class BaseAttachedProperty .

You do need to import the proper xmlns (XML namespace) to use it, which would be the namespace where the IsBusyProperty class is defined. If you want to use the one already defined in the Fasetto.Word library, the code would probably be:

xmlns:fas="clr-namespace:Fasetto.Word;assembly=Fasetto.Word"

...

<Button fas:IsBusyProperty.Value="{Binding LoginIsRunning}"/>

I'm not 100% sure if the assembly=Fasetto.Word part is correct, but Visual Studio should tell you what the correct value is if you start typing xmlns:fas="clr-namespace:Fasetto.Word . fas is just an abritrary name I picked from the first 3 letters of the the library name, but you can use anything as long as you're consitant. For more info on xmlns , check out the MSDN article .


If you want to create your own attached property using BaseAttachedProperty , you would do something like this:

public class SomeOtherProperty : BaseAttachedProperty<SomeOtherProperty, TypeOfProperty>
{
}

And then you would use it like this:

<Button yourns:SomeOtherProperty.Value="{Binding Something}"/>

Where yourns is the xmlns for whatever namespace you defined SomeOtherProperty in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM