public ViewModelBinding(ConsoleControl control, PropertyInfo controlProperty, ObservableObject viewModel, string observablePropertyName) { var viewModelObservableProperty = viewModel.GetType().GetProperty(observablePropertyName); if (viewModelObservableProperty.PropertyType != controlProperty.PropertyType && viewModelObservableProperty.PropertyType.IsSubclassOf(controlProperty.PropertyType) == false && viewModelObservableProperty.PropertyType.GetInterfaces().Contains(controlProperty.PropertyType) == false) { throw new InvalidOperationException($"ViewModel property '{viewModel.GetType().FullName}.{observablePropertyName}' of type {viewModelObservableProperty.PropertyType.FullName} is not compatible with control property '{controlProperty.DeclaringType.FullName}.{controlProperty.Name}' of type {controlProperty.PropertyType.FullName} "); } viewModel.SynchronizeForLifetime(observablePropertyName, () => { var newValue = viewModelObservableProperty.GetValue(viewModel); if (newValue == latestValue) { return; } latestValue = newValue; controlProperty.SetValue(control, newValue); }, control.LifetimeManager); control.SubscribeForLifetime(controlProperty.Name, () => { var newValue = controlProperty.GetValue(control); if (newValue == latestValue) { return; } latestValue = newValue; viewModelObservableProperty.SetValue(viewModel, newValue); }, control.LifetimeManager); }
public ViewModelBinding(ConsoleControl control, PropertyInfo controlProperty, ObservableObject viewModel, string observablePath, Func <object, object> mapper, Func <object, object> reverseMapper) { this.mapper = mapper; this.reverseMapper = reverseMapper; var exp = ObjectPathExpression.Parse(observablePath); var trace = exp.EvaluateAndTraceInfo(viewModel); var observableObject = trace[trace.Count - 2].Value as ObservableObject; var viewModelObservableProperty = trace.Last()?.MemberInfo as PropertyInfo; if (observableObject == null) { throw new InvalidOperationException($"ViewModel property '{viewModel.GetType().FullName}.{observablePath}' is not observable"); } if (viewModelObservableProperty == null) { throw new InvalidOperationException($"Cannot resolve ViewModel property '{viewModel.GetType().FullName}.{observablePath}'"); } if (mapper != null && reverseMapper != null) { if (viewModelObservableProperty.PropertyType != controlProperty.PropertyType && viewModelObservableProperty.PropertyType.IsSubclassOf(controlProperty.PropertyType) == false && viewModelObservableProperty.PropertyType.GetInterfaces().Contains(controlProperty.PropertyType) == false) { throw new InvalidOperationException($"ViewModel type '{viewModel.GetType().FullName} property {observablePath}' of type {viewModelObservableProperty.PropertyType.FullName} is not compatible with control property '{controlProperty.DeclaringType.FullName}.{controlProperty.Name}' of type {controlProperty.PropertyType.FullName} "); } } observableObject.SynchronizeForLifetime(trace.Last().MemberInfo.Name, () => { var newValue = viewModelObservableProperty.GetValue(observableObject); if (newValue == latestValue) { return; } latestValue = newValue; controlProperty.SetValue(control, mapper != null ? mapper(newValue) : newValue); }, control.LifetimeManager); control.SubscribeForLifetime(controlProperty.Name, () => { var newValue = controlProperty.GetValue(control); if (newValue == latestValue) { return; } latestValue = newValue; viewModelObservableProperty.SetValue(observableObject, reverseMapper != null ? reverseMapper(newValue) : newValue); }, control.LifetimeManager); }
public static ViewModelBinding OneWayBind <TControlPropertyType, TDataPropertyType>(ConsoleControl control, string propertyName, ObservableObject viewModel, string observablePath, Func <TDataPropertyType, TControlPropertyType> map) { ViewModelBinding ret = new ViewModelBinding(control, control.GetType().GetProperty(propertyName), viewModel, observablePath, (v) => { return(map((TDataPropertyType)v)); }, null); return(ret); }
public ViewModelBinding(ConsoleControl control, PropertyInfo controlProperty, ObservableObject viewModel, string observablePath) : this(control, controlProperty, viewModel, observablePath, null, null) { }
public ViewModelBinding(ConsoleControl control, string propertyName, ObservableObject viewModel, string observablePath) : this(control, control.GetType().GetProperty(propertyName), viewModel, observablePath) { }