mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-03-02 15:50:51 +08:00
71 lines
2.3 KiB
C#
71 lines
2.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AIStudio.Wpf.ADiagram.Commands
|
|
{
|
|
/// <summary>
|
|
/// Represents each node of nested properties expression and takes care of
|
|
/// subscribing/unsubscribing INotifyPropertyChanged.PropertyChanged listeners on it.
|
|
/// </summary>
|
|
internal class PropertyObserverNode
|
|
{
|
|
private readonly Action _action;
|
|
private INotifyPropertyChanged _inpcObject;
|
|
|
|
public PropertyInfo PropertyInfo { get; }
|
|
public PropertyObserverNode Next { get; set; }
|
|
|
|
public PropertyObserverNode(PropertyInfo propertyInfo, Action action)
|
|
{
|
|
PropertyInfo = propertyInfo ?? throw new ArgumentNullException(nameof(propertyInfo));
|
|
_action = () =>
|
|
{
|
|
action?.Invoke();
|
|
if (Next == null) return;
|
|
Next.UnsubscribeListener();
|
|
GenerateNextNode();
|
|
};
|
|
}
|
|
|
|
public void SubscribeListenerFor(INotifyPropertyChanged inpcObject)
|
|
{
|
|
_inpcObject = inpcObject;
|
|
_inpcObject.PropertyChanged += OnPropertyChanged;
|
|
|
|
if (Next != null) GenerateNextNode();
|
|
}
|
|
|
|
private void GenerateNextNode()
|
|
{
|
|
var nextProperty = PropertyInfo.GetValue(_inpcObject);
|
|
if (nextProperty == null) return;
|
|
if (!(nextProperty is INotifyPropertyChanged nextInpcObject))
|
|
throw new InvalidOperationException("Trying to subscribe PropertyChanged listener in object that " +
|
|
$"owns '{Next.PropertyInfo.Name}' property, but the object does not implements INotifyPropertyChanged.");
|
|
|
|
Next.SubscribeListenerFor(nextInpcObject);
|
|
}
|
|
|
|
private void UnsubscribeListener()
|
|
{
|
|
if (_inpcObject != null)
|
|
_inpcObject.PropertyChanged -= OnPropertyChanged;
|
|
|
|
Next?.UnsubscribeListener();
|
|
}
|
|
|
|
private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
{
|
|
if (e?.PropertyName == PropertyInfo.Name || string.IsNullOrEmpty(e?.PropertyName))
|
|
{
|
|
_action?.Invoke();
|
|
}
|
|
}
|
|
}
|
|
}
|