/// <summary> /// Examines the type of the bound object and initializes all neccessary structures /// that are needed before binding can start. This methods to be called once for /// each type passed as <paramref name="target"/> (not for each object of that type). /// </summary> /// <param name="target">bound object</param> /// <param name="sourceType">Type of binding (model/view helper).</param> private void PrepareBindingTo(IBindable target, EBindingSourceType sourceType) { if (sourceType == EBindingSourceType.Model) { PropertyInfo modelProperty = FindFieldByAttribute(Type, typeof(ModelElementAttribute)); ModelElementType = modelProperty.GetValue(target, null).GetType(); if (ModelElementType == null) { throw new InvalidOperationException(string.Format("Model property for type {0} is not assigned or the property is not marked with ModelElementAttribute", Type)); } if (!initializationInProgress) { Debug.WriteLine("Model binding for type " + target.GetType().Name + " with model type " + ModelElementType.Name); } ModelSourceGetter = DynamicMethodCompiler.CreateGetHandler(ModelElementType, modelProperty); CreateBindingFunctions(sourceType, ModelElementType); } if (sourceType == EBindingSourceType.View) { PropertyInfo viewHelperProperty = FindFieldByAttribute(Type, typeof(ViewHelperElementAttribute)); ViewHelperType = viewHelperProperty.GetValue(target, null).GetType(); if (ViewHelperType == null) { throw new InvalidOperationException(string.Format("ViewHelper for type {0} is not assigned or the property is not marked with ViewHelperElementAttribute", Type)); } if (!initializationInProgress) { Debug.WriteLine("View binding for type " + target.GetType().Name + " with view type " + ViewHelperType.Name); } ViewSourceGetter = DynamicMethodCompiler.CreateGetHandler(ViewHelperType, viewHelperProperty); CreateBindingFunctions(sourceType, ViewHelperType); } }
/// <summary> /// Gets <see cref="TypeBindingData"/> for type of <paramref name="bindable"/>. /// New instance is created <see cref="TypeBindingData"/> and type is examined /// if this type was not used before. /// </summary> /// <param name="bindable">The bindable.</param> /// <returns><see cref="TypeBindingData"/> for type of <paramref name="bindable"/></returns> private static TypeBindingData GetTypeBindingData(this IBindable bindable) { Type t = bindable.GetType(); if (!_typeBindingData.ContainsKey(t)) { _typeBindingData[t] = new TypeBindingData(bindable.GetType()); } return(_typeBindingData[t]); }
/// <summary> /// Binds the underlying <see cref="IBindable{TBind}"/> to the specified value. /// </summary> /// <param name="value"> The value to bind to. </param> public void Bind(TBind value) { if (value == null) { throw new ArgumentNullException($"Cannot bind this '{_bindable.GetType().Name}' to a null instance of '{typeof(TBind).Name}'."); } if (_value != null && !_allowRebinding) { throw new InvalidOperationException($"This '{_bindable.GetType().Name}' is already bound to an instance of '{_value.GetType().Name}'."); } _check?.Invoke(value); _value = value; }
public static void ApplyBindingsRecursive(IBindable obj) { var type = obj.GetType(); // if it has children (f.e. BindableList) we forward all their events and child events to if (obj is IBindableContainer) { foreach (var child in ((IBindableContainer)obj).GetBindableChildren()) { ApplyBindingsRecursive(child); } } // go through all field an look for the [CreateBindable] attribute var fields = type.GetFields(); foreach (var field in fields) { var fieldValue = field.GetValue(obj); if (field.GetCustomAttributes(typeof(BindableAttribute), true).Any()) { var castedfieldValue = (IBindable)fieldValue; obj.ForwardOnChange(castedfieldValue); // UnityEngine.Debug.Log("forwarding from field '" + field.Name + "' " + castedfieldValue.GetType().Name + " to " + obj.GetType().Name); ApplyBindingsRecursive(castedfieldValue); } } }
void IBindable <T> .BindTo(IBindable <T> them) { if (!(them is Bindable <T> tThem)) { throw new InvalidCastException($"Can't bind to a bindable of type {them.GetType()} from a bindable of type {GetType()}."); } BindTo(tThem); }
public static object GetProperty(this IBindable This, string propertyName) { return(typeof(ExcelInterfaces.BindExtensions) .GetRuntimeMethod(nameof(BindExtensions.GetPropertyEx), new[] { This.GetType(), typeof(string) }) //.GetRuntimeMethods().Single(x => x.Name == nameof(BindExtensions.BindPropertyEx)) .MakeGenericMethod(This.Object.GetType(), This.Object.GetType().GetRuntimeProperty(propertyName).PropertyType) .Invoke(null, new object[] { This, propertyName })); }
public void TestParse(Type type, object input, object output) { IBindable bindable = (IBindable)Activator.CreateInstance(typeof(Bindable <>).MakeGenericType(type), type == typeof(string) ? "" : Activator.CreateInstance(type)); bindable.Parse(input); object value = bindable.GetType().GetProperty(nameof(Bindable <object> .Value), BindingFlags.Public | BindingFlags.Instance)?.GetValue(bindable); Assert.That(value, Is.EqualTo(output)); }
public string GetName() { if (m_Bindable == null) { return($"{m_Element.name}({m_Element.GetType().Name})"); } else { return($"{m_Bindable.Path}({m_Bindable.GetType().Name})"); } }
public static IBinding BindDataContextProperty(this IBindable bindable, string bindingPropertyName, Type valueType, IBinding binding) { var type = bindable.GetType(); var bindingProperty = GetFirstDeclaredProperty(type, bindingPropertyName).GetValue(bindable); var types = new Type[] { typeof(IndirectBinding <>).MakeGenericType(valueType), typeof(DualBindingMode), valueType, valueType }; var bindDataContextMethod = bindingProperty.GetType().GetRuntimeMethod("BindDataContext", types); var defaultValue = Activator.CreateInstance(valueType); return((IBinding)bindDataContextMethod.Invoke(bindingProperty, new object[] { binding, DualBindingMode.TwoWay, defaultValue, defaultValue })); }
/// <summary> /// When creating copies or clones of a Mod, this method will be called /// to copy explicitly adjusted user settings from <paramref name="target"/>. /// The base implementation will transfer the value via <see cref="Bindable{T}.Parse"/> /// or by binding and unbinding (if <paramref name="source"/> is an <see cref="IBindable"/>) /// and should be called unless replaced with custom logic. /// </summary> /// <param name="target">The target bindable to apply the adjustment to.</param> /// <param name="source">The adjustment to apply.</param> internal virtual void CopyAdjustedSetting(IBindable target, object source) { if (source is IBindable sourceBindable) { // copy including transfer of default values. target.BindTo(sourceBindable); target.UnbindFrom(sourceBindable); } else { if (!(target is IParseable parseable)) { throw new InvalidOperationException($"Bindable type {target.GetType().ReadableName()} is not {nameof(IParseable)}."); } parseable.Parse(source); } }
public static IBindingExpression SetBinding(IBindable target, string targetProperty, Binding binding) { if (target == null) { throw new ArgumentNullException("target"); } if (string.IsNullOrEmpty(targetProperty)) { throw new ArgumentNullException("targetProperty"); } if (binding == null) { throw new ArgumentNullException("binding"); } var binderKey = _Bindings.SingleOrDefault((kvp) => kvp.Key.Object == target && kvp.Key.Property == targetProperty).Key; IBindingExpression bindingExpression = null; object nestedTarget = target; var element = target as Element; PropertyInfo propertyInfo = target.GetType().GetNestedProperty(ref nestedTarget, targetProperty, false); var targetReady = propertyInfo != null && nestedTarget != null; if (targetReady) { if (_BindingExpressions == null) { _BindingExpressions = new List <IBindingExpression>(); } bindingExpression = GetBindingExpression(target, targetProperty); if (bindingExpression == null) { bindingExpression = new BindingExpression(binding, propertyInfo, nestedTarget) { Element = element }; _BindingExpressions.Add(bindingExpression); var INPC = bindingExpression.Binding.Source as INotifyPropertyChanged; if (INPC != null) { INPC.PropertyChanged -= HandleDataContextPropertyChanged; INPC.PropertyChanged += HandleDataContextPropertyChanged; } } } else { if (binderKey == null) { _Bindings.Add(new PropertyBinder() { Object = target, Property = targetProperty }, binding); } else { _Bindings[binderKey] = binding; } } return(bindingExpression); }
public static IBindingExpression SetBinding(IBindable target, string targetProperty, Binding binding) { if (target == null) throw new ArgumentNullException("target"); if (string.IsNullOrEmpty(targetProperty)) throw new ArgumentNullException("targetProperty"); if (binding == null) throw new ArgumentNullException("binding"); var binderKey =_Bindings.SingleOrDefault((kvp)=>kvp.Key.Object == target && kvp.Key.Property == targetProperty).Key; IBindingExpression bindingExpression = null; object nestedTarget = target; var element = target as IElement; var name = string.Concat(targetProperty, "Property.Value"); MemberInfo memberInfo = target.GetType().GetNestedMember(ref nestedTarget, name, false); if (memberInfo != null) { binding.TargetPath = name; binding.Target = nestedTarget; } else { nestedTarget = target; memberInfo = target.GetType().GetNestedMember(ref nestedTarget, targetProperty, false); } var targetReady = memberInfo != null && nestedTarget != null; if (targetReady) { if (_BindingExpressions == null) _BindingExpressions = new List<IBindingExpression>(); bindingExpression = GetBindingExpression(target, targetProperty); if (bindingExpression == null) { bindingExpression = new BindingExpression(binding, memberInfo, nestedTarget) { Element = element }; _BindingExpressions.Add(bindingExpression); var vmINPC = bindingExpression.Binding.Source as INotifyPropertyChanged; if (vmINPC != null) { vmINPC.PropertyChanged -= HandleDataContextPropertyChanged; vmINPC.PropertyChanged += HandleDataContextPropertyChanged; } var viewINPC = bindingExpression.Binding.ViewSource as INotifyPropertyChanged; if (viewINPC != null) { viewINPC.PropertyChanged -= HandleDataContextPropertyChanged; viewINPC.PropertyChanged += HandleDataContextPropertyChanged; } } } else { if (binderKey == null) _Bindings.Add(new PropertyBinder() { Object = target, Property = targetProperty }, binding); else _Bindings[binderKey] = binding; } return bindingExpression; }
public static IBindingExpression SetBinding(IBindable target, string targetProperty, Binding binding) { if (target == null) { throw new ArgumentNullException("target"); } if (string.IsNullOrEmpty(targetProperty)) { throw new ArgumentNullException("targetProperty"); } if (binding == null) { throw new ArgumentNullException("binding"); } var binderKey = _Bindings.SingleOrDefault((kvp) => kvp.Key.Object == target && kvp.Key.Property == targetProperty).Key; IBindingExpression bindingExpression = null; object nestedTarget = target; var element = target as IElement; var name = string.Concat(targetProperty, "Property.Value"); MemberInfo memberInfo = target.GetType().GetNestedMember(ref nestedTarget, name, false); if (memberInfo != null) { binding.TargetPath = name; binding.Target = nestedTarget; } else { nestedTarget = target; memberInfo = target.GetType().GetNestedMember(ref nestedTarget, targetProperty, false); } var targetReady = memberInfo != null && nestedTarget != null; if (targetReady) { if (_BindingExpressions == null) { _BindingExpressions = new List <IBindingExpression>(); } bindingExpression = GetBindingExpression(target, targetProperty); if (bindingExpression == null) { bindingExpression = new BindingExpression(binding, memberInfo, nestedTarget) { Element = element }; _BindingExpressions.Add(bindingExpression); var vmINPC = bindingExpression.Binding.Source as INotifyPropertyChanged; if (vmINPC != null) { vmINPC.PropertyChanged -= HandleDataContextPropertyChanged; vmINPC.PropertyChanged += HandleDataContextPropertyChanged; } var viewINPC = bindingExpression.Binding.ViewSource as INotifyPropertyChanged; if (viewINPC != null) { viewINPC.PropertyChanged -= HandleDataContextPropertyChanged; viewINPC.PropertyChanged += HandleDataContextPropertyChanged; } } } else { if (binderKey == null) { _Bindings.Add(new PropertyBinder() { Object = target, Property = targetProperty }, binding); } else { _Bindings[binderKey] = binding; } } return(bindingExpression); }
public static IBindingExpression SetBinding(IBindable target, string targetProperty, Binding binding) { if (target == null) throw new ArgumentNullException("target"); if (string.IsNullOrEmpty(targetProperty)) throw new ArgumentNullException("targetProperty"); if (binding == null) throw new ArgumentNullException("binding"); var binderKey =_Bindings.SingleOrDefault((kvp)=>kvp.Key.Object == target && kvp.Key.Property == targetProperty).Key; IBindingExpression bindingExpression = null; object nestedTarget = target; var element = target as Element; PropertyInfo propertyInfo = target.GetType().GetNestedProperty(ref nestedTarget, targetProperty, false); var targetReady = propertyInfo != null && nestedTarget != null; if (targetReady) { if (_BindingExpressions == null) _BindingExpressions = new List<IBindingExpression>(); bindingExpression = GetBindingExpression(target, targetProperty); if (bindingExpression == null) { bindingExpression = new BindingExpression(binding, propertyInfo, nestedTarget) { Element = element }; _BindingExpressions.Add(bindingExpression); var INPC = bindingExpression.Binding.Source as INotifyPropertyChanged; if (INPC != null) { INPC.PropertyChanged -= HandleDataContextPropertyChanged; INPC.PropertyChanged += HandleDataContextPropertyChanged; } } } else { if (binderKey == null) _Bindings.Add(new PropertyBinder() { Object = target, Property = targetProperty }, binding); else _Bindings[binderKey] = binding; } return bindingExpression; }