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);
        }