123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- using System;
- using System.Windows;
- namespace HandyControl.Interactivity;
- internal sealed class NameResolver
- {
- private string _name;
- private FrameworkElement _nameScopeReferenceElement;
- private FrameworkElement ActualNameScopeReferenceElement
- {
- get
- {
- if (NameScopeReferenceElement != null && Interaction.IsElementLoaded(NameScopeReferenceElement))
- return GetActualNameScopeReference(NameScopeReferenceElement);
- return null;
- }
- }
- private bool HasAttempedResolve { get; set; }
- public string Name
- {
- get =>
- _name;
- set
- {
- var oldObject = Object;
- _name = value;
- UpdateObjectFromName(oldObject);
- }
- }
- public FrameworkElement NameScopeReferenceElement
- {
- get =>
- _nameScopeReferenceElement;
- set
- {
- var nameScopeReferenceElement = NameScopeReferenceElement;
- _nameScopeReferenceElement = value;
- OnNameScopeReferenceElementChanged(nameScopeReferenceElement);
- }
- }
- public DependencyObject Object
- {
- get
- {
- if (string.IsNullOrEmpty(Name) && HasAttempedResolve)
- return NameScopeReferenceElement;
- return ResolvedObject;
- }
- }
- private bool PendingReferenceElementLoad { get; set; }
- private DependencyObject ResolvedObject { get; set; }
- public event EventHandler<NameResolvedEventArgs> ResolvedElementChanged;
- private FrameworkElement GetActualNameScopeReference(FrameworkElement initialReferenceElement)
- {
- var element = initialReferenceElement;
- if (!IsNameScope(initialReferenceElement))
- return element;
- return initialReferenceElement.Parent as FrameworkElement ?? element;
- }
- private bool IsNameScope(FrameworkElement frameworkElement)
- {
- return frameworkElement.Parent is FrameworkElement parent && parent.FindName(Name) != null;
- }
- private void OnNameScopeReferenceElementChanged(FrameworkElement oldNameScopeReference)
- {
- if (PendingReferenceElementLoad)
- {
- oldNameScopeReference.Loaded -= OnNameScopeReferenceLoaded;
- PendingReferenceElementLoad = false;
- }
- HasAttempedResolve = false;
- UpdateObjectFromName(Object);
- }
- private void OnNameScopeReferenceLoaded(object sender, RoutedEventArgs e)
- {
- PendingReferenceElementLoad = false;
- NameScopeReferenceElement.Loaded -= OnNameScopeReferenceLoaded;
- UpdateObjectFromName(Object);
- }
- private void OnObjectChanged(DependencyObject oldTarget, DependencyObject newTarget)
- {
- ResolvedElementChanged?.Invoke(this, new NameResolvedEventArgs(oldTarget, newTarget));
- }
- private void UpdateObjectFromName(DependencyObject oldObject)
- {
- DependencyObject obj2 = null;
- ResolvedObject = null;
- if (NameScopeReferenceElement != null)
- {
- if (!Interaction.IsElementLoaded(NameScopeReferenceElement))
- {
- NameScopeReferenceElement.Loaded += OnNameScopeReferenceLoaded;
- PendingReferenceElementLoad = true;
- return;
- }
- if (!string.IsNullOrEmpty(Name))
- {
- var actualNameScopeReferenceElement = ActualNameScopeReferenceElement;
- if (actualNameScopeReferenceElement != null)
- obj2 = actualNameScopeReferenceElement.FindName(Name) as DependencyObject;
- }
- }
- HasAttempedResolve = true;
- ResolvedObject = obj2;
- if (!Equals(oldObject, Object))
- OnObjectChanged(oldObject, Object);
- }
- }
|