Last active
May 9, 2021 13:25
-
-
Save mr5z/15b6f275532103edfed65deecbf50638 to your computer and use it in GitHub Desktop.
Property event to observable.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Observable | |
{ | |
private object actionCollection = null!; | |
private MethodInfo? methodInfo; | |
public ActionCollection<TModel> From<TModel>(TModel target) where TModel : INotifyPropertyChanged | |
{ | |
RegisterPropertyChanged(target); | |
return BuildActionCollection<TModel>(); | |
} | |
private void RegisterPropertyChanged<TModel>(TModel target) where TModel : INotifyPropertyChanged | |
{ | |
target.PropertyChanged -= Model_PropertyChanged; | |
target.PropertyChanged += Model_PropertyChanged; | |
} | |
private ActionCollection<TModel> BuildActionCollection<TModel>() where TModel : notnull | |
{ | |
var type = typeof(ActionCollection<TModel>); | |
methodInfo = type.GetMethod(nameof(ActionCollection<TModel>.Get)); | |
actionCollection = new ActionCollection<TModel>(); | |
return (ActionCollection<TModel>)actionCollection; | |
} | |
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e) | |
{ | |
var actionList = GetActionList(); | |
if (!actionList.ContainsKey(e.PropertyName)) | |
return; | |
var type = sender.GetType(); | |
var property = type.GetProperty(e.PropertyName); | |
var value = property.GetValue(sender, null); | |
var action = actionList[e.PropertyName]; | |
action(value); | |
} | |
private IReadOnlyDictionary<string, Action<object>> GetActionList() | |
{ | |
var returnValue = methodInfo!.Invoke(actionCollection, null); | |
return (IReadOnlyDictionary<string, Action<object>>)returnValue; | |
} | |
public class ActionCollection<TModel> where TModel : notnull | |
{ | |
private readonly Dictionary<string, Action<object>> actionList = new(); | |
public ActionCollection<TModel> On<TProperty>(Expression<Func<TModel, TProperty>> expression, Action<TProperty> action) | |
{ | |
var propertyName = expression.GetMemberName(); | |
actionList[propertyName] = (param) => action((TProperty)param); | |
return this; | |
} | |
public IReadOnlyDictionary<string, Action<object>> Get() => actionList; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment