How to get the RegisterName of an event sender?

I have an SelectionChanged event for several Comboboxes. Is it possible to get the RegisterName of the Combobox which has fired the event? I would like to avoid using the Combobox.Name thing as shown below:

ComboBox cbx = e.Source as ComboBox;
string cbxName = cbx.Name;

1 answer

  • answered 2019-07-19 11:20 Misaz

    You can get it using this method. Solution is based on reflection and access internal method and internal object of WPF. So it is not garantuated that it will work after Microsoft release new version of .NET Framework and WPF. There are also not garantuated that it everytime returns internal System.Xaml.NameScope object. If it dont, method throws NotSupportedException. Don't forget to handle it. Also don't forget to handle other exceptions thrown in case of internal structure has changed.

    public string FindRegisteredName(FrameworkElement control) {
        BindingFlags FindScopeFlags = BindingFlags.NonPublic | BindingFlags.Static;
        Type[] methodArgumentTypes = new Type[] { typeof(DependencyObject) };
        var FindScope = typeof(FrameworkElement).GetMethod("FindScope", FindScopeFlags, null, methodArgumentTypes, null);
    
        var result = FindScope.Invoke(null, new object[] { this });
        Type resultType = result.GetType();
        if (resultType.FullName == "System.Xaml.NameScope") {
            try {
                HybridDictionary map = (HybridDictionary)resultType.GetField("_nameMap", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(result);
                foreach (DictionaryEntry entry in map) {
                    if (entry.Value == control) {
                        return (string)entry.Key;
                    }
                }
            } catch (Exception) {
                throw new NotSupportedException("Cannot find registration name because internal structure has changed");
            }
        } else {
            throw new NotSupportedException("Cannot detect registered names because FindScope returned unexpected type " + result.GetType().FullName);
        }
    
        throw new KeyNotFoundException("Cannot find registered name of control.");
    }
    

    I also recommend you using normal Name property instead of registering names manually.