void InitializeDataContext(Element xmlNode, FrameworkElement instance, FrameworkElement parentInstance) { if (_isBuildingTemplate) { instance.DataContext = DataContext; return; } var subControlDataContextAttribute = xmlNode.Attributes["DataContext"]; if (subControlDataContextAttribute == null) { var bindingInfo = new BindingInfo { BindingMode = BindingMode.OneWay, Source = parentInstance, SourcePath = "DataContext", Target = instance, TargetPath = "DataContext" }; bindingInfo.Connect(); return; } var bi = BindingInfo.TryParseExpression(subControlDataContextAttribute.NodeValue); if (bi == null) { throw new InvalidOperationException("InvalidBindingExpression:" + subControlDataContextAttribute.NodeValue); } bi.BindingMode = BindingMode.OneWay; bi.Source = parentInstance; bi.SourcePath = "DataContext." + bi.SourcePath.Path; bi.Target = instance; bi.TargetPath = "DataContext"; bi.Connect(); }
internal override List<BindingInfo> CreateBindings(FrameworkElement element, object dataItem, bool twoWay) { BindingInfo bindingData = new BindingInfo(); if (twoWay && this.BindingTarget != null) { bindingData.BindingExpression = element.GetBindingExpression(this.BindingTarget); if (bindingData.BindingExpression != null) { bindingData.BindingTarget = this.BindingTarget; bindingData.Element = element; return new List<BindingInfo> { bindingData }; } } foreach (DependencyProperty bindingTarget in element.GetDependencyProperties(false)) { bindingData.BindingExpression = element.GetBindingExpression(bindingTarget); if (bindingData.BindingExpression != null && bindingData.BindingExpression.ParentBinding == this.Binding) { this.BindingTarget = bindingTarget; bindingData.BindingTarget = this.BindingTarget; bindingData.Element = element; return new List<BindingInfo> { bindingData }; } } return base.CreateBindings(element, dataItem, twoWay); }
void ProcessAttribute(object instance, string name, string value) { var nameUpperCase = name.ToUpperCase(); if (nameUpperCase == "DATACONTEXT" || name == AttributeName_d_designerdataContext) { return; } if (name == "class") { name = "Class"; } var targetProperty = ReflectionHelper.FindProperty(instance, name, FindPropertyFlag); if (targetProperty != null && name != targetProperty.Name) { name = targetProperty.Name; } var bi = BindingInfo.TryParseExpression(value); if (bi != null) { var eventInfo = ReflectionHelper.FindEvent(instance, name, FindPropertyFlag); if (eventInfo != null) { var methodInfo = ReflectionHelper.GetMethodInfo(DataContext, bi.SourcePath.Path); var handler = Delegate.CreateDelegate(eventInfo.AddMethod.ParameterTypes.First(), DataContext, methodInfo); eventInfo.AddEventHandler(instance, handler); return; } if (name.Contains(".") == false) { if (targetProperty == null) { var htmlBindingInfo = new HTMLBindingInfo { Source = instance, SourcePath = new PropertyPath("DataContext." + bi.SourcePath.Path), Target = instance.As <FrameworkElement>()._root, TargetPath = name, BindingMode = BindingMode.OneWay }; if (bi.BindingMode == BindingMode.TwoWay && HTMLBindingInfo.TargetCanUpdateSource(htmlBindingInfo.Target)) { htmlBindingInfo.BindingMode = BindingMode.TwoWay; } htmlBindingInfo.Connect(); return; } } bi.SourcePath = new PropertyPath("DataContext." + bi.SourcePath.Path); bi.Source = instance; bi.Target = instance; bi.TargetPath = name; bi.Connect(); return; } if (targetProperty != null) { if (targetProperty.PropertyType.IsEnum) { ReflectionHelper.SetPropertyValue(instance, name, Enum.Parse(targetProperty.PropertyType, value, true)); return; } var converterAttributes = targetProperty.GetCustomAttributes(typeof(TypeConverterAttribute)); var firstConverterAtribute = converterAttributes?.FirstOrDefault(); if (firstConverterAtribute != null) { var converter = (TypeConverterAttribute)firstConverterAtribute; var valueConverter = (IValueConverter)Activator.CreateInstance(converter._type); var convertedValue = valueConverter.Convert(value, targetProperty.PropertyType, null, CultureInfo.CurrentCulture); ReflectionHelper.SetPropertyValue(instance, targetProperty.Name, convertedValue); return; } var propertyValue = Cast.To(value, targetProperty.PropertyType, CultureInfo.CurrentCulture); ReflectionHelper.SetPropertyValue(instance, targetProperty.Name, propertyValue); return; } if (name.StartsWith("on.")) { var eventName = name.RemoveFromStart("on."); // support this format: this.Notify(OnContactClicked) if (value.StartsWith("this.")) { var viewInvocationExpressionInfo = ViewInvocationExpressionInfo.Parse(value); var methodName = viewInvocationExpressionInfo.MethodName; var mi = Caller.GetType().GetMethod(methodName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); instance.As <FrameworkElement>().On(eventName, () => { if (mi == null) { throw new MissingMemberException(Caller.GetType().FullName + "->" + methodName); } mi.Invoke(Caller, viewInvocationExpressionInfo.Parameters.ToArray()); }); return; } var methodInfo = Caller.GetType().GetMethod(value, ReflectionHelper.AllBindings); instance.As <FrameworkElement>().On(eventName, () => { if (methodInfo == null) { throw new MissingMemberException(Caller.GetType().FullName + "::" + value); } methodInfo.Invoke(Caller); }); return; } if (nameUpperCase.StartsWith("CSS.")) { var styleAttributeName = name.Substring(4); instance.As <FrameworkElement>()._root.Css(styleAttributeName, value); return; } if (nameUpperCase == "X.NAME" || nameUpperCase == "X:NAME") { ReflectionHelper.SetNonStaticField(Caller, value, instance); return; } instance.As <FrameworkElement>()._root.Attr(name, value); }