Open sandboxFocusImprove this doc

XAM054: Ambiguous Validation or Change Handler Method of a Dependency Property

Severity Error
Reported by PostSharp.Patterns.Xaml
Message Error in the [<Aspect>] aspect applied to property <Property>: type <DeclaringType> contains more than one method named "<Method>".

Cause

The DependencyPropertyAttribute and AttachedPropertyAttribute aspects look up two methods by name in the class that declares the property:

  • the validation method, named ValidateName by default, where Name is the name of the property, or named by the <xref:PostSharp.Patterns.Xaml.DependencyPropertyBaseAttribute.ValidateValueMethod> property;
  • the property-changed method, named OnNameChanged by default, or named by the <xref:PostSharp.Patterns.Xaml.DependencyPropertyBaseAttribute.PropertyChangedMethod> property.

Each of these methods can have several signatures, so the aspect does not choose between overloads. PostSharp reports XAM054 when <DeclaringType> declares more than one method named <Method>, whatever their visibility and signatures. The validation method is looked up first.

In the following example, ContactCard declares two overloads of OnPhoneChanged.

using System;
using System.Windows;
using PostSharp.Patterns.Xaml;

namespace Errors.XAM054_Error;

public class ContactCard : DependencyObject
{
    // ContactCard declares two methods named OnPhoneChanged, so the aspect cannot choose the change handler.
    [DependencyProperty]
    public string? Phone { get; set; }

    private void OnPhoneChanged()
    {
        Console.WriteLine( $"Phone changed to {this.Phone}." );
    }

    private void OnPhoneChanged( DependencyProperty property )
    {
        Console.WriteLine( $"Property {property.Name} changed to {this.Phone}." );
    }
}

public static class Program
{
    public static void Main()
    {
        var card = new ContactCard { Phone = "+1 555 0100" };
        card.Phone = "+1 555 0199";
    }
}
error XAM054: XAM054_Error.cs(11,20): Error in the [DependencyProperty] aspect applied to property Errors.XAM054_Error.ContactCard.Phone: type Errors.XAM054_Error.ContactCard contains more than one method named "OnPhoneChanged".

Resolution

Keep a single method with the name, and give the other overloads another name. If the overloads are needed for another purpose, give the handler a distinct name and set it with <xref:PostSharp.Patterns.Xaml.DependencyPropertyBaseAttribute.ValidateValueMethod> or <xref:PostSharp.Patterns.Xaml.DependencyPropertyBaseAttribute.PropertyChangedMethod>.

In the following example, ContactCard keeps the overload that receives the DependencyProperty, which the aspect calls each time Phone changes.

using System;
using System.Windows;
using PostSharp.Patterns.Xaml;

namespace Errors.XAM054_Fixed;

public class ContactCard : DependencyObject
{
    // ContactCard declares a single method named OnPhoneChanged, which the aspect uses as the change handler.
    [DependencyProperty]
    public string? Phone { get; set; }

    private void OnPhoneChanged( DependencyProperty property )
    {
        Console.WriteLine( $"Property {property.Name} changed to {this.Phone}." );
    }
}

public static class Program
{
    public static void Main()
    {
        var card = new ContactCard { Phone = "+1 555 0100" };
        card.Phone = "+1 555 0199";
    }
}
Property Phone changed to +1 555 0100.
Property Phone changed to +1 555 0199.

See Also

Reference

<xref:PostSharp.Patterns.Xaml.DependencyPropertyBaseAttribute.ValidateValueMethod>
<xref:PostSharp.Patterns.Xaml.DependencyPropertyBaseAttribute.PropertyChangedMethod>
DependencyPropertyAttribute
AttachedPropertyAttribute

Other Resources

Dependency Property