AutomationID attached property changed

90 Views Asked by At

I have a wpf application, OnLoaded event I'am attaching an automationId to my FrameworkElement (element):
element.SetValue(AutomationProperties.AutomationIdProperty, path); 

But this automationId is modified somewhere in the code. I want to add a listner or something that can help me to debug. I am waiting for something like

AutomationProperties.AutomationIdProperty+= AutomationIdChanged; 
private void AutomationIdChanged(object sender, EventArgs e)
       {
         var oldVal =   e.oldValue ;
         var newVal=   e.NewValue;
       }
1

There are 1 best solutions below

0
denys-vega On

Important: You did not mention the target framework. My answer is based on .NET Framework 4.6.2.

You can use the DependencyPropertyDescriptor and call to AddValueChanged to listen for changes. Unfortunately, this callback function does not provide the old value. However, I will provide a workaround.

I would like to solve it implementing an extension method, named DebugAutomationIdChanged:

public static class FrameworkElementExt
{
    private static readonly ConditionalWeakTable<FrameworkElement, string> AutomationIdCwt =
        new ConditionalWeakTable<FrameworkElement, string>();

    public static void DebugAutomationIdChanged(this FrameworkElement element)
    {
        var descriptor = DependencyPropertyDescriptor.FromProperty(
            AutomationProperties.AutomationIdProperty,
            element.GetType()
        );

        descriptor.AddValueChanged(element, delegate
        {
            var currentValue = AutomationProperties.GetAutomationId(element);
            if (AutomationIdCwt.TryGetValue(element, out var oldValue))
            {
                Debug.WriteLine($"AutomationId changed: '{oldValue}' -> '{currentValue}'");
                AutomationIdCwt.Remove(element);
            }
            else
            {
                Debug.WriteLine($"AutomationId changed: '{currentValue}'");
            }

            AutomationIdCwt.Add(element, currentValue);
        });
    }
}

Later, in your code behind, you can call it like this (some code has been removed to keep simplicity):

...
element.DebugAutomationIdChanged();
element.SetValue(AutomationProperties.AutomationIdProperty, "fe-01");
...