Skip to content

Instantly share code, notes, and snippets.

@mr5z
Last active May 9, 2021 13:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mr5z/15b6f275532103edfed65deecbf50638 to your computer and use it in GitHub Desktop.
Save mr5z/15b6f275532103edfed65deecbf50638 to your computer and use it in GitHub Desktop.
Property event to observable.
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