Exemplo n.º 1
0
        Dictionary <char, List <string> > _charToSimpleHighContrastNames; //this dictionary serves to link the first letter of the theme-dependent resource to the simple high contrast names that start with that letter.
        //The objective is to reduce the amount of strings we try to find in the resource (probably a minor improvement in performance but it's something)

        /// <summary>
        /// Tries to find the resourceKey in the Generic.xaml resources of the assembly. Note: the resource currently need to be defined in Project/Themes/generic.xaml
        /// </summary>
        /// <param name="assemblyWhereGenericXamlIsLocated">The assembly where we will look into.</param>
        /// <param name="resourceKey">The resource to find in the Assembly's resources.</param>
        /// <returns>The resource associated with the given key in the given assembly's resources.</returns>
        internal object TryFindResourceInGenericXaml(Assembly assemblyWhereGenericXamlIsLocated, object resourceKey)
        {
            ResourceDictionary resourceDictionary = null;

            if (_assemblyToResourceDictionary.ContainsKey(assemblyWhereGenericXamlIsLocated))
            {
                resourceDictionary = _assemblyToResourceDictionary[assemblyWhereGenericXamlIsLocated];
            }
            else
            {
#if !BRIDGE
                string assemblyName = assemblyWhereGenericXamlIsLocated.GetName().Name;
#else
                string assemblyName = INTERNAL_BridgeWorkarounds.GetAssemblyNameWithoutCallingGetNameMethod(assemblyWhereGenericXamlIsLocated);
#endif
                assemblyName = assemblyName.Replace(" ", "ǀǀ").Replace(".", "ǀǀ");
                string factoryTypeName = MakeTitleCase("ǀǀ" + assemblyName + "ǀǀComponentǀǀThemesǀǀGenericǀǀXamlǀǀFactory");
                Type   resourceDictionaryFactoryType = assemblyWhereGenericXamlIsLocated.GetType(factoryTypeName);
                if (resourceDictionaryFactoryType != null)
                {
                    resourceDictionary = (ResourceDictionary)resourceDictionaryFactoryType.GetMethod("Instantiate").Invoke(null, null);
                    _assemblyToResourceDictionary.Add(assemblyWhereGenericXamlIsLocated, resourceDictionary);
                }
            }

            if (resourceDictionary != null && resourceDictionary.ContainsKey(resourceKey))
            {
                return(resourceDictionary[resourceKey]);
            }

            return(null);
        }
        public void UpdateRow(int index, object item)
        {
            foreach (var prop in item.GetType().GetProperties())
            {
                object newValue = null;
                try
                {
#if CSHTML5
                    if (INTERNAL_BridgeWorkarounds.MethodInfoIsStatic_SimulatorCompatible(prop.GetMethod))
#else
                    if (prop.GetMethod.IsStatic) //have to check for that because for some reason Bridge throws an Exception when trying to call prop.GetValue(item) when it is a static property.
#endif
                    {
                        newValue = prop.GetValue(null);
                    }
                    else
                    {
                        newValue = prop.GetValue(item);
                    }
                }
                catch (Exception) { }

                this.updateCell(index, this.columnIndexes[prop.Name], newValue);
            }
        }
Exemplo n.º 3
0
        internal static object INTERNAL_ConvertFromString(string keyTimeCode)
        {
            try
            {
                if (keyTimeCode == "Uniform")
                {
                    throw new NotImplementedException("The Value \"Uniform\" for keyTime is not supported yet.");
                }
                else if (keyTimeCode == "Paced")
                {
                    throw new NotImplementedException("The Value \"Paced\" for keyTime is not supported yet.");
                }
                else if (keyTimeCode.EndsWith("%"))
                {
                    throw new NotImplementedException("The percentage values for keyTime are not supported yet.");
                }
                else
                {
#if BRIDGE
                    TimeSpan timeSpan = INTERNAL_BridgeWorkarounds.TimeSpanParse(keyTimeCode, false);
#else
                    TimeSpan timeSpan = TimeSpan.Parse(keyTimeCode);
#endif
                    return(new KeyTime(timeSpan));
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Invalid KeyTime: " + keyTimeCode, ex);
            }
        }
        /// <summary>
        /// Returns the first child of the specified type (recursively).
        /// </summary>
        /// <typeparam name="T">The type to lookup.</typeparam>
        /// <param name="parent">The parent element.</param>
        /// <returns>The first child of the specified type.</returns>
        public static T GetChildOfType <T>(UIElement parent) where T : UIElement
        {
            if (parent == null || parent.INTERNAL_VisualChildrenInformation == null)
            {
                return(null);
            }

            foreach (INTERNAL_VisualChildInformation visualChildInformation in
#if BRIDGE
                     INTERNAL_BridgeWorkarounds.GetDictionaryValues_SimulatorCompatible(parent.INTERNAL_VisualChildrenInformation)
#else
                     parent.INTERNAL_VisualChildrenInformation.Values
#endif
                     )
            {
                var child  = visualChildInformation.INTERNAL_UIElement;
                var result = (child as T) ?? GetChildOfType <T>(child);
                if (result != null)
                {
                    return(result);
                }
            }

            return(null);
        }
Exemplo n.º 5
0
        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator()
        {
#if BRIDGE
            return(INTERNAL_BridgeWorkarounds.GetDictionaryValues_SimulatorCompatible(_visualStateGroups).GetEnumerator());
#else
            return(_visualStateGroups.Values.GetEnumerator());
#endif
        }
Exemplo n.º 6
0
        public IEnumerator <VisualStateGroup> GetEnumerator()
        {
#if BRIDGE
            return(INTERNAL_BridgeWorkarounds.GetDictionaryValues_SimulatorCompatible(_visualStateGroups).GetEnumerator());
#else
            return(_visualStateGroups.Values.GetEnumerator());
#endif
        }
Exemplo n.º 7
0
        internal override void UpdateValue()
        {
            if (DependencyProperty != null)
            {
                //this.ValueType = this.DependencyProperty.GetTargetType();

                UpdateValueAndIsBroken(((DependencyObject)Source).GetValue(DependencyProperty), CheckIsBroken());
            }
            else if (PropertyInfo != null)
            {
                //TODO: this.ValueType = PropertyInfo.PropertyType;
                //this.ValueType = null; //todo: don't know what this is for
                try
                {
#if BRIDGE
                    //Bridge throws an exception when trying to call GetValue through PropertyInfo.GetValue on a Static Property while putting an instance as a parameter (which should not be the case in my opinion).
                    //Because of that, we need to check whether the property is Static and then accordingly call GetValue with either null or the instance as a parameter.
                    object     propertyValue = null;
                    MethodInfo methodInfo    = PropertyInfo.GetMethod;
                    if (INTERNAL_BridgeWorkarounds.MethodInfoIsStatic_SimulatorCompatible(methodInfo))
                    {
                        propertyValue = PropertyInfo.GetValue(null);
                    }
                    else
                    {
                        propertyValue = PropertyInfo.GetValue(this.Source);
                    }
                    UpdateValueAndIsBroken(propertyValue, CheckIsBroken());
#else
                    UpdateValueAndIsBroken(PropertyInfo.GetValue(this.Source), CheckIsBroken());
#endif
                }
                catch
                {
                    UpdateValueAndIsBroken(null, CheckIsBroken());
                }
            }
            else if (FieldInfo != null)
            {
                try
                {
                    UpdateValueAndIsBroken(FieldInfo.GetValue(this.Source), CheckIsBroken());
                }
                catch
                {
                    UpdateValueAndIsBroken(null, CheckIsBroken());
                }
            }
            else if (BindsDirectlyToSource)
            {
                this.UpdateValueAndIsBroken(Source, CheckIsBroken(BindsDirectlyToSource));
            }
            else
            {
                //this.ValueType = null;
                this.UpdateValueAndIsBroken(null, CheckIsBroken());
            }
        }
Exemplo n.º 8
0
        Dictionary <char, List <string> > _charToSimpleHighContrastNames; //this dictionary serves to link the first letter of the theme-dependent resource to the simple high contrast names that start with that letter.
        //The objective is to reduce the amount of strings we try to find in the resource (probably a minor improvement in performance but it's something)

        /// <summary>
        /// Tries to find the resourceKey in the Generic.xaml resources of the assembly. Note: the resource currently need to be defined in Project/Themes/generic.xaml
        /// </summary>
        /// <param name="assemblyWhereGenericXamlIsLocated">The assembly where we will look into.</param>
        /// <param name="resourceKey">The resource to find in the Assembly's resources.</param>
        /// <returns>The resource associated with the given key in the given assembly's resources.</returns>
        internal object TryFindResourceInGenericXaml(Assembly assemblyWhereGenericXamlIsLocated, object resourceKey)
        {
            ResourceDictionary resourceDictionary = null;

            if (_assemblyToResourceDictionary.ContainsKey(assemblyWhereGenericXamlIsLocated))
            {
                resourceDictionary = _assemblyToResourceDictionary[assemblyWhereGenericXamlIsLocated];
            }
            else
            {
#if !BRIDGE
                string assemblyName = assemblyWhereGenericXamlIsLocated.GetName().Name;
                // todo: instead of the following if, make it so that the Core project can generate the .g.cs files by itself (JSIL version, Bridge works fine) instead of relying on an external project (called DotNetForHtml5.Core.Styles). Note: given what the name of the assembly is, it should still be shortened to remove everything after the first comma.
                //Fixing the assemblyName so that the default styles can be found (the generic.xaml file that contains the default styles is located in a different project with a different namespace):
                if (assemblyName == "SLMigration.CSharpXamlForHtml5" || assemblyName == "CSharpXamlForHtml5" ||
                    assemblyName == "SLMigration.CSharpXamlForHtml5, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" || assemblyName == "CSharpXamlForHtml5, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
                {
                    assemblyName = "DotNetForHtml5.Core.Styles"; //Note: this is the name of the assembly where the default styles are defined (project DotNetForHtml5.Core.Styles in the DotNetForHtml5 solution).
                }
#else
                string assemblyName = INTERNAL_BridgeWorkarounds.GetAssemblyNameWithoutCallingGetNameMethod(assemblyWhereGenericXamlIsLocated);
#endif
                assemblyName = assemblyName.Replace(" ", "ǀǀ").Replace(".", "ǀǀ");
                string factoryTypeName = MakeTitleCase("ǀǀ" + assemblyName + "ǀǀComponentǀǀThemesǀǀGenericǀǀXamlǀǀFactory");
                Type   resourceDictionaryFactoryType = assemblyWhereGenericXamlIsLocated.GetType(factoryTypeName);
#if CSHTML5BLAZOR
                if (resourceDictionaryFactoryType == null)
                {
                    if (assemblyName == "OpenSilver") //We do this part because OpenSilver uses the generic.xaml.g.cs of the CSHTML5 Migration edition which in consequence has a different namespace than it would have if it was directly defined as xaml in OpenSilver.
                    {
                        assemblyName    = "Cshtml5ǀǀMigration";
                        factoryTypeName = MakeTitleCase("ǀǀ" + assemblyName + "ǀǀComponentǀǀThemesǀǀGenericǀǀXamlǀǀFactory");
                        resourceDictionaryFactoryType = assemblyWhereGenericXamlIsLocated.GetType(factoryTypeName);
                    }
                    else if (assemblyName == "OpenSilverǀǀUwpCompatible") //We do this part because OpenSilver uses the generic.xaml.g.cs of the CSHTML5 Migration edition which in consequence has a different namespace than it would have if it was directly defined as xaml in OpenSilver.
                    {
                        assemblyName    = "Cshtml5";
                        factoryTypeName = MakeTitleCase("ǀǀ" + assemblyName + "ǀǀComponentǀǀThemesǀǀGenericǀǀXamlǀǀFactory");
                        resourceDictionaryFactoryType = assemblyWhereGenericXamlIsLocated.GetType(factoryTypeName);
                    }
                }
#endif

                if (resourceDictionaryFactoryType != null)
                {
                    resourceDictionary = (ResourceDictionary)resourceDictionaryFactoryType.GetMethod("Instantiate").Invoke(null, null);
                    _assemblyToResourceDictionary.Add(assemblyWhereGenericXamlIsLocated, resourceDictionary);
                }
            }

            if (resourceDictionary != null && resourceDictionary.ContainsKey(resourceKey))
            {
                return(resourceDictionary[resourceKey]);
            }

            return(null);
        }
Exemplo n.º 9
0
        ///// <summary>
        ///// Subtracts the specified Windows.UI.Xaml.Duration from this Windows.UI.Xaml.Duration.
        ///// </summary>
        ///// <param name="duration">The Windows.UI.Xaml.Duration to subtract from this Windows.UI.Xaml.Duration.</param>
        ///// <returns>The subtracted Windows.UI.Xaml.Duration.</returns>
        //public Duration Subtract(Duration duration);

        ///// <summary>
        ///// Converts a Windows.UI.Xaml.Duration to a System.String representation.
        ///// </summary>
        ///// <returns>A System.String representation of this Windows.UI.Xaml.Duration.</returns>
        //public override string ToString();

        internal static object INTERNAL_ConvertFromString(string p)
        {
#if BRIDGE
            TimeSpan timeSpan = INTERNAL_BridgeWorkarounds.TimeSpanParse(p);
#else
            TimeSpan timeSpan = TimeSpan.Parse(p);
#endif
            return(new Duration(timeSpan));
        }
Exemplo n.º 10
0
        /// <summary>
        /// Returns an enumerator that iterates through the ResourceDictionary.
        /// </summary>
        /// <returns>A System.Collections.Generic.Dictionary{object,object}.Enumerator structure for the ResourceDictionary.</returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            //todo (maybe): change the enumerator so that it also goes through the elements of the merged Dictionaries

#if BRIDGE
            return(INTERNAL_BridgeWorkarounds.GetDictionaryEnumerator(_resourcesContainer));
#else
            return(_resourcesContainer.GetEnumerator());
#endif
        }
Exemplo n.º 11
0
        static object FindPage(Uri uri)
        {
            string assemblyName;
            string instancierName;

            GetXamlFileAssociatedClassInstancierName(uri, out assemblyName, out instancierName); //this method should only accept .xaml files (imo), it returns the name of the class we generated during the compilation, built from the assembly(gotten from either the uri, or the startingAssembly) and the file name.
#if BRIDGE
            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (INTERNAL_BridgeWorkarounds.GetAssemblyNameWithoutCallingGetNameMethod(assembly) == assemblyName)
                {
                    Type type = assembly.GetType(instancierName);
                    if (type != null)
                    {
                        MethodInfo methodInfo = type.GetMethod("Instantiate");
                        return(methodInfo.Invoke(null, null));
                    }
                    break;
                }
            }
#else
#if OPENSILVER
            if (true)
#elif BRIDGE
            if (CSHTML5.Interop.IsRunningInTheSimulator)
#endif
            {
                foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                {
                    if (assembly.GetName().Name == assemblyName)
                    {
                        Type type = assembly.GetType(instancierName);
                        if (type != null)
                        {
                            MethodInfo methodInfo = type.GetMethod("Instantiate");
                            return(methodInfo.Invoke(null, null));
                        }
                        break;
                    }
                }
            }
            else
            {
                object assembly = CSHTML5.Interop.ExecuteJavaScript(@"JSIL.GetAssembly($0, true)", assemblyName);
                object type     = CSHTML5.Interop.ExecuteJavaScript(@"JSIL.GetTypeFromAssembly($0, $1)", assembly, instancierName);
                if (!IsNullOrUndefined(type))
                {
                    object method = CSHTML5.Interop.ExecuteJavaScript(@"$0.GetMethod('Instantiate')", type);
                    return(CSHTML5.Interop.ExecuteJavaScript("$0.Invoke(null, null)", method));
                }
            }
#endif
            return(null);
        }
Exemplo n.º 12
0
        static object ConvertTimeSpanFromString(string str)
        {
            try
            {
#if BRIDGE
                TimeSpan returnValue = INTERNAL_BridgeWorkarounds.TimeSpanParse(str);
#else
                TimeSpan returnValue = TimeSpan.Parse(str);
#endif
                return(returnValue);
            }
            catch
            {
                throw new Exception("Xaml exception: cannot convert \"" + str + "\" to TimeSpan. " + AdviseToFixTheError);
            }
        }
Exemplo n.º 13
0
        internal void INTERNAL_UpdateBindingsSource()
        {
            if (_bindingExpressions != null)
            {
                foreach (BindingExpression bindingExpression in
#if BRIDGE
                         INTERNAL_BridgeWorkarounds.GetDictionaryValues_SimulatorCompatible(_bindingExpressions)
#else
                         _bindingExpressions.Values
#endif
                         )
                {
                    bindingExpression.OnSourceAvailable();
                }
            }
        }
Exemplo n.º 14
0
        public VisualStateGroup this[int index]
        {
            get
            {
#if BRIDGE
                return(INTERNAL_BridgeWorkarounds.GetDictionaryValues_SimulatorCompatible(_visualStateGroups).ElementAt(index));
#else
                return(_visualStateGroups.Values.ElementAt(index));
#endif
            }
            set
            {
                //todo: refresh the VisualStates
                throw new NotImplementedException();
                _visualStateGroups[_visualStateGroups.Keys.ElementAt(index)] = value;
            }
        }
Exemplo n.º 15
0
        public static IEnumerable GetAllRootUIElements() // IMPORTANT: This is called via reflection from the "Visual Tree Inspector" of the Simulator. If you rename or remove it, be sure to update the Simulator accordingly!
        {
            // Include the main window:
            yield return(Window.Current);

            // And all the popups:
            foreach (var popupRoot in
#if BRIDGE
                     INTERNAL_BridgeWorkarounds.GetDictionaryValues_SimulatorCompatible(PopupRootIdentifierToInstance)
#else
                     PopupRootIdentifierToInstance.Values
#endif
                     )
            {
                yield return(popupRoot);
            }
        }
Exemplo n.º 16
0
        ///// <summary>
        ///// Subtracts the specified Windows.UI.Xaml.Duration from this Windows.UI.Xaml.Duration.
        ///// </summary>
        ///// <param name="duration">The Windows.UI.Xaml.Duration to subtract from this Windows.UI.Xaml.Duration.</param>
        ///// <returns>The subtracted Windows.UI.Xaml.Duration.</returns>
        //public Duration Subtract(Duration duration);

        ///// <summary>
        ///// Converts a Windows.UI.Xaml.Duration to a System.String representation.
        ///// </summary>
        ///// <returns>A System.String representation of this Windows.UI.Xaml.Duration.</returns>
        //public override string ToString();

        internal static object INTERNAL_ConvertFromString(string p)
        {
            if (p.ToLower() == "forever")
            {
                return(Duration.Forever);
            }
            if (p.ToLower() == "automatic")
            {
                return(Duration.Automatic);
            }
#if BRIDGE
            TimeSpan timeSpan = INTERNAL_BridgeWorkarounds.TimeSpanParse(p);
#else
            TimeSpan timeSpan = TimeSpan.Parse(p);
#endif
            return(new Duration(timeSpan));
        }
Exemplo n.º 17
0
        public int IndexOf(VisualStateGroup item)
        {
            int i = 0;

            while (i < _visualStateGroups.Count)
            {
#if BRIDGE
                if (INTERNAL_BridgeWorkarounds.GetDictionaryValues_SimulatorCompatible(_visualStateGroups).ElementAt(i) == item)
#else
                if (_visualStateGroups.Values.ElementAt(i) == item)
#endif
                {
                    return(i);
                }
                ++i;
            }
            return(-1);
        }
Exemplo n.º 18
0
        internal static object INTERNAL_ConvertFromString(string colorcode)
        {
            try
            {
                // Check if the color is a named color:
                if (!colorcode.StartsWith("#"))
                {
                    Colors.INTERNAL_ColorsEnum namedColor = (Colors.INTERNAL_ColorsEnum)Enum.Parse(typeof(Colors.INTERNAL_ColorsEnum), colorcode, true); // Note: "TryParse" does not seem to work in JSIL.
                    return(INTERNAL_ConvertFromInt32((int)namedColor));
                }
                else
                {
                    colorcode = colorcode.Replace("#", "");
                    if (colorcode.Length == 6) // This is becaue XAML is tolerant when the user has forgot the alpha channel (eg. #DDDDDD for Gray).
                    {
                        colorcode = "FF" + colorcode;
                    }
#if !BRIDGE
                    int colorAsInt = int.Parse(colorcode.Replace("#", ""), NumberStyles.HexNumber);
#else
                    int colorAsInt;
                    if (CSHTML5.Interop.IsRunningInTheSimulator)
                    {
                        colorcode  = colorcode.Replace("#", "");
                        colorAsInt = INTERNAL_BridgeWorkarounds.HexToInt_SimulatorOnly(colorcode);
                    }
                    else
                    {
                        colorAsInt = Script.Write <int>("parseInt({0}, 16);", colorcode.Replace("#", ""));
                    }
#endif
                    return(INTERNAL_ConvertFromInt32(colorAsInt));
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Invalid color: " + colorcode, ex);
            }
        }
Exemplo n.º 19
0
        static string[] GetListOfLoadedAssemblies()
        {
            string[] listOfAssemblies;
            if (CSHTML5.Interop.IsRunningInTheSimulator)
            {
#if !BRIDGE
                listOfAssemblies = AppDomain.CurrentDomain.GetAssemblies().Select(a => a.GetName().Name).ToArray();
#else
                listOfAssemblies = AppDomain.CurrentDomain.GetAssemblies().Select(a => INTERNAL_BridgeWorkarounds.GetAssemblyNameWithoutCallingGetNameMethod(a)).ToArray();
#endif
            }
            else
            {
#if !BRIDGE
                listOfAssemblies = JSIL.Verbatim.Expression("Object.keys(JSIL.AssemblyShortNames)");
#else
                listOfAssemblies = AppDomain.CurrentDomain.GetAssemblies().Select(a => GetAssemblyName(a.FullName)).ToArray();//Script.Write<string[]>("Object.keys(JSIL.AssemblyShortNames);");
#endif
            }
            return(listOfAssemblies);
        }
Exemplo n.º 20
0
        static void AttachVisualChild_Private(UIElement child, UIElement parent)
        {
            //
            // THIS IS WHAT THE FINAL STRUCTURE IN THE DOM TREE WILL LOOK LIKE:
            //
            //     domElementWhereToPlaceChildStuff
            //     --- [wrapperForChild]
            //     --- --- [innerDivOfWrapperForChild]
            //     --- --- --- [additionalOutsideDivForMargins, aka BoxSizing]
            //     --- --- --- --- outerDomElement
            //


            //--------------------------------------------------------
            // APPLY IMPLICIT AND DEFAULT STYLES:
            //--------------------------------------------------------

#if PERFSTAT
            var t = Performance.now();
#endif

            //See if the child has a Style, if not, try to find an implicitStyle for its Type.
            FrameworkElement childAsFrameworkElement = child as FrameworkElement;
            if (childAsFrameworkElement != null)
            {
                if (childAsFrameworkElement.Style == null)
                {
                    //-----------------------------
                    // APPLY IMPLICIT STYLE IF ANY:
                    //-----------------------------

                    Style style = null;
                    //Note if anyone wonders: if type B inherits from type A, an Implicit Style defined for type A is ignored by elements of type B (tested in an SL project).
                    if (UpdateElementInheritedImplicitStyles(childAsFrameworkElement, (FrameworkElement)parent))
                    {
                        Type childType = child.GetType();
                        foreach (ResourceDictionary resourceDictionary in childAsFrameworkElement.INTERNAL_InheritedImplicitStyles) // Note: "INTERNAL_InheritedImplicitStyles" is not null because the method above returned True.
                        {
                            if (resourceDictionary.ContainsKey(childType))
                            {
                                style = resourceDictionary[childType] as Style;
                                break;
                            }
                        }
                    }
                    if (style != null)
                    {
                        childAsFrameworkElement.Style = style;
                        childAsFrameworkElement.INTERNAL_IsImplicitStyle = true; //Note: it is important that we do this AFTER setting the Style property to the ImplicitStyle because the setter of the Style Property sets it to false to avoid removing styles that are not implicit.
                    }
                }

                //Add the effect of the setters of the default Style on the child:
                Style childDefaultStyle = childAsFrameworkElement.INTERNAL_defaultStyle;
                if (childDefaultStyle != null)
                {
                    //----------------------------
                    // APPLY DEFAULT STYLE IF ANY:
                    //----------------------------

                    //get the list of setters of the currently applied style on the element and of the default style:
                    Dictionary <DependencyProperty, Setter> normalStyleDictionary = null;
                    bool childHasStyle = childAsFrameworkElement.Style != null;
                    if (childHasStyle)
                    {
                        normalStyleDictionary = childAsFrameworkElement.Style.GetDictionaryOfSettersFromStyle();
                    }
                    Dictionary <DependencyProperty, Setter> defaultStyleDictionary = childDefaultStyle.GetDictionaryOfSettersFromStyle();

                    //for all the setters the default style has, that are not on properties already affected by the normal style, we apply them like a normal style (we basically do the same as what we do on each setter in FrameworkElement.Style_Changed):
                    foreach (DependencyProperty prop in
#if BRIDGE
                             INTERNAL_BridgeWorkarounds.GetDictionaryKeys_SimulatorCompatible(defaultStyleDictionary)
#else
                             defaultStyleDictionary.Keys
#endif
                             )
                    {
                        if (!childHasStyle || !normalStyleDictionary.ContainsKey(prop))
                        {
                            Setter setter = defaultStyleDictionary[prop];

                            childDefaultStyle.SetterValueChanged -= childAsFrameworkElement.StyleSetterValueChanged;
                            childDefaultStyle.SetterValueChanged += childAsFrameworkElement.StyleSetterValueChanged;

                            INTERNAL_PropertyStorage storage = INTERNAL_PropertyStore.GetStorageOrCreateNewIfNotExists(childAsFrameworkElement, setter.Property);
                            INTERNAL_PropertyStore.SetLocalStyleValue(storage, setter.Value);
                        }
                    }
                }
            }

#if PERFSTAT
            Performance.Counter("VisualTreeManager: Apply implicit and default styles", t);
#endif

            //--------------------------------------------------------
            // PREPARE THE PARENT:
            //--------------------------------------------------------

#if PERFSTAT
            var t0 = Performance.now();
#endif

            // Prepare the parent DOM structure so that it is ready to contain the child (for example, in case of a grid, we need to (re)create the rows and columns where to place the elements).
            //parent.INTERNAL_UpdateDomStructureIfNecessary();

            object domElementWhereToPlaceChildStuff = (parent.GetDomElementWhereToPlaceChild(child) ?? parent.INTERNAL_InnerDomElement);

            // A "wrapper for child" is sometimes needed between the child and the parent (for example in case of a grid). It is usually one or more DIVs that fit in-between the child and the parent, and that are used to position the child within the parent.
            object innerDivOfWrapperForChild;
            object wrapperForChild = parent.CreateDomChildWrapper(domElementWhereToPlaceChildStuff, out innerDivOfWrapperForChild);
            bool   comparison1     = (wrapperForChild == null);                                    // Note: we need due to a bug of JSIL where translation fails if we do not use this temp variable.
            bool   comparison2     = (innerDivOfWrapperForChild == null);                          // Note: we need due to a bug of JSIL where translation fails if we do not use this temp variable.
            bool   doesParentRequireToCreateAWrapperForEachChild = (!comparison1 && !comparison2); // Note: The result is "True" for complex structures such as tables, false otherwise (cf. documentation in "INTERNAL_VisualChildInformation" class).

#if PERFSTAT
            Performance.Counter("VisualTreeManager: Prepare the parent", t0);
#endif

            //--------------------------------------------------------
            // CONTINUE WITH THE OTHER STEPS (OR DEFER TO WHEN THE ELEMENT IS VISIBLE, IF THE OPTIMIZATION TO NOT LOAD COLLAPSED CONTROLS IS ENABLED):
            //--------------------------------------------------------

            if (!EnableOptimizationWhereCollapsedControlsAreNotLoaded || child.Visibility != Visibility.Collapsed)
            {
                AttachVisualChild_Private_FinalStepsOnlyIfControlIsVisible(
                    child,
                    parent,
                    doesParentRequireToCreateAWrapperForEachChild,
                    innerDivOfWrapperForChild,
                    domElementWhereToPlaceChildStuff,
                    wrapperForChild);
            }
            else
            {
                child.INTERNAL_DeferredLoadingWhenControlBecomesVisible = () =>
                {
                    AttachVisualChild_Private_FinalStepsOnlyIfControlIsVisible(
                        child,
                        parent,
                        doesParentRequireToCreateAWrapperForEachChild,
                        innerDivOfWrapperForChild,
                        domElementWhereToPlaceChildStuff,
                        wrapperForChild);
                };
            }
        }
        static void AttachVisualChild_Private_MainSteps(UIElement child,
                                                        UIElement parent,
                                                        bool doesParentRequireToCreateAWrapperForEachChild,
                                                        object innerDivOfWrapperForChild,
                                                        object domElementWhereToPlaceChildStuff,
                                                        object wrapperForChild)
        {
#if REWORKLOADED
            if (INTERNAL_VisualTreeOperation.Current.Root == null)
            {
                INTERNAL_VisualTreeOperation.Current.Root = parent;
            }
#endif
            //#if CSHTML5BLAZOR && DEBUG
            //            string childIndentity = child + (child != null ? " (" + child.GetHashCode() + ")" : "");
            //            string parentIndentity = parent + (parent != null ? " (" + parent.GetHashCode() + ")" : "");
            //            Console.WriteLine("OPEN SILVER DEBUG: VisualTreeManager : AttachVisualChild_Private_FinalStepsOnlyIfControlIsVisible: " + childIndentity + " attached to " + parentIndentity);
            //#endif

            //--------------------------------------------------------
            // CREATE THE DIV FOR THE MARGINS (OPTIONAL):
            //--------------------------------------------------------

#if PERFSTAT
            var t1 = Performance.now();
#endif

            // Determine if an additional DIV for handling margins is needed:
            object additionalOutsideDivForMargins = null;
            var    margin = ((FrameworkElement)child).Margin;
            bool   containsNegativeMargins = (margin.Left < 0d || margin.Top < 0d || margin.Right < 0d || margin.Bottom < 0d);
#if ONLY_ADD_DIV_FOR_MARGINS_WHEN_MARGINS_NOT_ZERO
            bool isADivForMarginsNeeded = !(parent is Canvas) && !(child is Inline) && child is FrameworkElement;  // Note: In a Canvas, we don't want to add the additional DIV because there are no margins and we don't want to interfere with the pointer events by creating an additional DIV.
            if (isADivForMarginsNeeded)
            {
                var horizontalAlign = ((FrameworkElement)child).HorizontalAlignment;
                var verticalAlign   = ((FrameworkElement)child).VerticalAlignment;
                isADivForMarginsNeeded = !(margin.Left == 0 && margin.Top == 0 && margin.Right == 0 && margin.Bottom == 0 && horizontalAlign == HorizontalAlignment.Stretch && verticalAlign == VerticalAlignment.Stretch);
            }
#else
            bool isADivForMarginsNeeded = !(parent is Canvas) && // Note: In a Canvas, we don't want to add the additional DIV because there are no margins and we don't want to interfere with the pointer events by creating an additional DIV.
                                          !(child is Inline);      // Note: inside a TextBlock we do not want the HTML DIV because we want to create HTML SPAN elements only (otherwise there would be unwanted line returns).
#endif
            if (isADivForMarginsNeeded)
            {
                // Determine where to place it:
                object whereToPlaceDivForMargins =
                    (doesParentRequireToCreateAWrapperForEachChild
                    ? innerDivOfWrapperForChild
                    : domElementWhereToPlaceChildStuff);

                // Create and append the DIV for handling margins and append:
                additionalOutsideDivForMargins = INTERNAL_HtmlDomManager.CreateDomElementAndAppendIt("div", whereToPlaceDivForMargins, parent); //todo: check if the third parameter should be the child or the parent (make something with margins and put a mouseenter in the parent then see if the event is triggered).

                // Style the DIV for handling margins:
                var style = INTERNAL_HtmlDomManager.GetDomElementStyleForModification(additionalOutsideDivForMargins);
                style.boxSizing = "border-box";
                if (child is FrameworkElement &&
                    (((FrameworkElement)child).HorizontalAlignment == HorizontalAlignment.Stretch && double.IsNaN(((FrameworkElement)child).Width)))
                {
                    if (!containsNegativeMargins)
                    {
                        style.width = "100%";
                    }
                }
                if (child is FrameworkElement &&
                    (((FrameworkElement)child).VerticalAlignment == VerticalAlignment.Stretch && double.IsNaN(((FrameworkElement)child).Height)))
                {
                    style.height = "100%";
                }
            }

#if PERFSTAT
            Performance.Counter("VisualTreeManager: Create the DIV for the margin", t1);
#endif

            //--------------------------------------------------------
            // PREPARE THE CHILD:
            //--------------------------------------------------------

#if PERFSTAT
            var t2 = Performance.now();
#endif

            // Determine where to place the child:
            object whereToPlaceTheChild = (isADivForMarginsNeeded
                ? additionalOutsideDivForMargins : (doesParentRequireToCreateAWrapperForEachChild
                    ? innerDivOfWrapperForChild
                    : domElementWhereToPlaceChildStuff));

            // Set the "Parent" property of the Child (IMPORTANT: we need to do that before child.CreateDomElement because the type of the parent is used to display the child correctly):
            child.INTERNAL_VisualParent = parent;

            // Set the "ParentWindow" property so that the element knows where to display popups:
            child.INTERNAL_ParentWindow = parent.INTERNAL_ParentWindow;

            // Create and append the DOM structure of the Child:
            object domElementWhereToPlaceGrandChildren = null;
            object outerDomElement;
            bool   isChildAControl = child is Control;
            if (child.INTERNAL_HtmlRepresentation == null)
            {
                bool hasTemplate = isChildAControl && ((Control)child).HasTemplate;
                if (hasTemplate)
                {
                    outerDomElement = ((Control)child).CreateDomElementForControlTemplate(whereToPlaceTheChild, out domElementWhereToPlaceGrandChildren);
                }
                else
                {
                    outerDomElement = child.CreateDomElement(whereToPlaceTheChild, out domElementWhereToPlaceGrandChildren);
                }
            }
            else
            {
                outerDomElement = INTERNAL_HtmlDomManager.CreateDomFromStringAndAppendIt(child.INTERNAL_HtmlRepresentation, whereToPlaceTheChild, child);
            }

            // Initialize the "Width" and "Height" of the child DOM structure:
            if (child is FrameworkElement)
            {
                FrameworkElement.INTERNAL_InitializeOuterDomElementWidthAndHeight(((FrameworkElement)child), outerDomElement);
            }

            // Update the DOM structure of the Child (for example, if the child is a Grid, this will render its rows and columns):
            child.INTERNAL_UpdateDomStructureIfNecessary();

            // For debugging purposes (to better read the output html), add a class to the outer DIV that tells us the corresponding type of the element (Border, StackPanel, etc.):
            INTERNAL_HtmlDomManager.SetDomElementAttribute(outerDomElement, "class", child.GetType().ToString());

#if PERFSTAT
            Performance.Counter("VisualTreeManager: Prepare the child", t2);
#endif

            //--------------------------------------------------------
            // REMEMBER ALL INFORMATION FOR FUTURE USE:
            //--------------------------------------------------------

#if PERFSTAT
            var t3 = Performance.now();
#endif

            // Remember the DIVs:
            child.INTERNAL_OuterDomElement = outerDomElement;
            child.INTERNAL_InnerDomElement = domElementWhereToPlaceGrandChildren;
            child.INTERNAL_AdditionalOutsideDivForMargins            = additionalOutsideDivForMargins ?? outerDomElement;
            child.INTERNAL_InnerDivOfTheChildWrapperOfTheParentIfAny = doesParentRequireToCreateAWrapperForEachChild ? innerDivOfWrapperForChild : null;

            // Remember the information about the "VisualChildren":
            if (parent.INTERNAL_VisualChildrenInformation == null)
            {
                parent.INTERNAL_VisualChildrenInformation = new Dictionary <UIElement, INTERNAL_VisualChildInformation>();
            }
            parent.INTERNAL_VisualChildrenInformation.Add(child,
                                                          new INTERNAL_VisualChildInformation()
            {
                INTERNAL_UIElement = child,
                INTERNAL_OptionalChildWrapper_OuterDomElement             = wrapperForChild,
                INTERNAL_OptionalChildWrapper_ChildWrapperInnerDomElement = innerDivOfWrapperForChild
            });

#if PERFSTAT
            Performance.Counter("VisualTreeManager: Remember all info for future use", t3);
#endif

            //--------------------------------------------------------
            // HANDLE SPECIAL CASES:
            //--------------------------------------------------------

#if PERFSTAT
            var t4 = Performance.now();
#endif

            // If we are inside a canvas, we set the position to "absolute":
            if (parent is Canvas)
            {
                INTERNAL_HtmlDomManager.GetDomElementStyleForModification(outerDomElement).position = "absolute"; //todo: test if this works properly
            }

            UIElement.SynchronizeForceInheritProperties(child, parent);

#if REVAMPPOINTEREVENTS
            UIElement.INTERNAL_UpdateCssPointerEvents(child);
#else
            // If the current element is inside a Grid, we need to explicitly set its CSS property "PointerEvents=auto" because its parent child wrapper has "PointerEvents=none" in order to prevent its child wrappers from overlapping each other and thus preventing clicks on some children.
            if (parent is Grid && child is FrameworkElement) //todo: generalize this code so that we have no hard-reference on the Grid control, and third-party controls can use the same mechanics.
            {
                var frameworkElement = ((FrameworkElement)child);
                FrameworkElement.INTERNAL_UpdateCssPointerEventsPropertyBasedOnIsHitTestVisibleAndIsEnabled(frameworkElement, frameworkElement.IsHitTestVisible, frameworkElement.IsEnabled);
            }
#endif

            // Reset the flag that tells if we have already applied the RenderTransformOrigin (this is useful to ensure that the default RenderTransformOrigin is (0,0) like in normal XAML, instead of (0.5,0.5) like in CSS):
            child.INTERNAL_RenderTransformOriginHasBeenApplied = false;

#if PERFSTAT
            Performance.Counter("VisualTreeManager: Handle special cases", t4);
#endif

            //--------------------------------------------------------
            // HANDLE EVENTS:
            //--------------------------------------------------------

#if PERFSTAT
            var t5 = Performance.now();
#endif

            // Register DOM events if any:
            child.INTERNAL_AttachToDomEvents();

#if PERFSTAT
            Performance.Counter("VisualTreeManager: Handle events", t5);
#endif
            //--------------------------------------------------------
            // HANDLE INHERITED PROPERTIES:
            //--------------------------------------------------------

#if PERFSTAT
            var t6 = Performance.now();
#endif

            // Get the Inherited properties and pass them to the direct children:
            foreach (DependencyProperty dependencyProperty in
#if BRIDGE
                     INTERNAL_BridgeWorkarounds.GetDictionaryKeys_SimulatorCompatible(parent.INTERNAL_AllInheritedProperties)
#else
                     parent.INTERNAL_AllInheritedProperties.Keys
#endif
                     )
            {
                bool recursively = false; // We don't want a recursion here because the "Attach" method is already recursive due to the fact that we raise property changed on the Children property, which causes to reattach the subtree.
                INTERNAL_PropertyStorage storage = parent.INTERNAL_AllInheritedProperties[dependencyProperty];
                child.SetInheritedValue(dependencyProperty, INTERNAL_PropertyStore.GetEffectiveValue(storage), recursively);
            }

#if PERFSTAT
            Performance.Counter("Handle inherited properties", t6);
#endif

            //--------------------------------------------------------
            // SET "ISLOADED" PROPERTY AND CALL "ONATTACHED" EVENT:
            //--------------------------------------------------------

            // Tell the control that it is now present into the visual tree:
            child._isLoaded = true;

            // Raise the "OnAttached" event:
            child.INTERNAL_OnAttachedToVisualTree(); // IMPORTANT: Must be done BEFORE "RaiseChangedEventOnAllDependencyProperties" (for example, the ItemsControl uses this to initialize its visual)

            //--------------------------------------------------------
            // RENDER THE ELEMENTS BY APPLYING THE CSS PROPERTIES:
            //--------------------------------------------------------

            // Defer rendering when the control is not visible to when becomes visible (note: when this option is enabled, we do not apply the CSS properties of the UI elements that are not visible. Those property are applied later, when the control becomes visible. This option results in improved performance.)
            bool enableDeferredRenderingOfCollapsedControls =
                EnableOptimizationWhereCollapsedControlsAreNotRendered ||
                EnableOptimizationWhereCollapsedControlsAreLoadedLast ||
                EnableOptimizationWhereCollapsedControlsAreNotLoaded;

            if (enableDeferredRenderingOfCollapsedControls && !child.IsVisible)
            {
                child.INTERNAL_DeferredRenderingWhenControlBecomesVisible = () =>
                {
                    RenderElementsAndRaiseChangedEventOnAllDependencyProperties(child);
                };
            }
            else
            {
                RenderElementsAndRaiseChangedEventOnAllDependencyProperties(child);
            }

            //--------------------------------------------------------
            // HANDLE BINDING:
            //--------------------------------------------------------

#if PERFSTAT
            var t9 = Performance.now();
#endif

            child.INTERNAL_UpdateBindingsSource();

#if PERFSTAT
            Performance.Counter("VisualTreeManager: Handle binding", t9);
#endif

            //--------------------------------------------------------
            // HANDLE TABINDEX:
            //--------------------------------------------------------

            // For GotFocus and LostFocus to work, the DIV specified by "INTERNAL_OptionalSpecifyDomElementConcernedByFocus"
            // (or the OuterDomElement otherwise) needs to have the "tabIndex" attribute set. Therefore we need to always set
            // it (unless IsTabStop is False) to its current value (default is Int32.MaxValue). At the time when this code was
            // written, there was no way to automatically call the "OnChanged" on a dependency property if no value was set.

#if !REWORKLOADED
            // IMPORTANT: This needs to be done AFTER the "OnApplyTemplate" (for example, the TextBox sets the "INTERNAL_OptionalSpecifyDomElementConcernedByFocus" in the "OnApplyTemplate").
            if (isChildAControl)
            {
                if (!(child is ContentPresenter) && !(child is TextBlock)) //ContentPresenter should not count in tabbing, as well as TextBlock (especially since TextBlock is not supposed to be a Control).
                {
                    Control.TabIndexProperty_MethodToUpdateDom(child, ((Control)child).TabIndex);
                }
            }
#endif

            //--------------------------------------------------------
            // APPLY THE VISIBILITY:
            //--------------------------------------------------------

            Visibility childVisibility = child.Visibility;
            if (childVisibility == Visibility.Collapsed)
            {
                UIElement.INTERNAL_ApplyVisibility(child, childVisibility);
            }

            //--------------------------------------------------------
            // RAISE THE "SIZECHANGED" EVENT:
            //--------------------------------------------------------
#if !REWORKLOADED
#if PERFSTAT
            var t10 = Performance.now();
#endif

            // Raise the "SizeChanged" event: (note: in XAML, the "SizeChanged" event is called before the "Loaded" event)
            // IMPORTANT: This event needs to be raised AFTER the "OnApplyTemplate" and AFTER the "IsLoaded=true" (for example, it is used in the ScrollBar implementation).
            if (child is FrameworkElement)
            {
                ((FrameworkElement)child).INTERNAL_SizeChangedWhenAttachedToVisualTree();
            }

#if PERFSTAT
            Performance.Counter("VisualTreeManager: Raise size changed event", t10);
#endif

            //--------------------------------------------------------
            // RAISE THE "LOADED" EVENT:
            //--------------------------------------------------------
#if PERFSTAT
            var t11 = Performance.now();
#endif

            // Raise the "Loaded" event: (note: in XAML, the "loaded" event of the children is called before the "loaded" event of the parent)
            if (child is FrameworkElement)
            {
                ((FrameworkElement)child).INTERNAL_RaiseLoadedEvent();
            }

            child.StartManagingPointerPositionForPointerExitedEventIfNeeded();

#if PERFSTAT
            Performance.Counter("VisualTreeManager: Raise Loaded event", t11);
#endif
#else
            INTERNAL_VisualTreeOperation.Current.Enqueue(child);
#endif
        }
Exemplo n.º 22
0
        private static void Style_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var frameworkElement = (FrameworkElement)d;

            if (!frameworkElement.INTERNAL_DoNotApplyStyle)
            {
                Style newStyle = (Style)e.NewValue;
                Style oldStyle = (Style)e.OldValue;

                Dictionary <DependencyProperty, Setter> oldStyleDictionary = new Dictionary <DependencyProperty, Setter>();
                if (oldStyle != null)
                {
                    oldStyleDictionary = oldStyle.GetDictionaryOfSettersFromStyle();
                }
                Dictionary <DependencyProperty, Setter> newStyleDictionary = new Dictionary <DependencyProperty, Setter>();
                if (newStyle != null)
                {
                    newStyleDictionary = newStyle.GetDictionaryOfSettersFromStyle();
                }

#if PERFSTAT
                var t0 = Performance.now();
#endif
                frameworkElement.RecursivelyUnregisterFromStyleChangedEvents(oldStyle);
#if PERFSTAT
                Performance.Counter("RecursivelyUnregisterFromStyleChangedEvents", t0);
#endif

#if PERFSTAT
                var t1 = Performance.now();
#endif
                frameworkElement.RecursivelyRegisterToStyleChangedEvents(newStyle);
#if PERFSTAT
                Performance.Counter("RecursivelyRegisterToStyleChangedEvents", t1);
#endif

                foreach (Setter oldSetter in
#if BRIDGE
                         INTERNAL_BridgeWorkarounds.GetDictionaryValues_SimulatorCompatible(oldStyleDictionary)
#else
                         oldStyleDictionary.Values
#endif
                         )
                {
                    if (oldSetter.Property != null) // Note: it can be null for example in the XAML text editor during design time, because the "DependencyPropertyConverter" class returns "null".
                    {
                        if (!newStyleDictionary.ContainsKey(oldSetter.Property))
                        {
                            INTERNAL_PropertyStorage storage = INTERNAL_PropertyStore.GetStorage(d, oldSetter.Property, createAndSaveNewStorageIfNotExists: false); //the createAndSaveNewStorageIfNotExists's value should have no actual meaning here because the PropertyStorage should have been created when applying the style.
                            INTERNAL_PropertyStore.ResetLocalStyleValue(storage);
                        }
                    }

                    // Reset the information that tells which Style the Setter belongs to (this is used so that when the Value of the Setter changes, the Setter can notify its parent Style):
                    oldSetter.INTERNAL_ParentStyle = null;
                }

                foreach (Setter newSetter in
#if BRIDGE
                         INTERNAL_BridgeWorkarounds.GetDictionaryValues_SimulatorCompatible(newStyleDictionary)
#else
                         newStyleDictionary.Values
#endif
                         )
                {
                    if (newSetter.Property != null) // Note: it can be null for example in the XAML text editor during design time, because the "DependencyPropertyConverter" class returns "null".
                    {
                        if (!oldStyleDictionary.ContainsKey(newSetter.Property) || oldStyleDictionary[newSetter.Property] != newSetter.Value)
                        {
                            INTERNAL_PropertyStorage storage = INTERNAL_PropertyStore.GetStorage(frameworkElement, newSetter.Property, createAndSaveNewStorageIfNotExists: true); //the createAndSaveNewStorageIfNotExists's value should have no actual meaning here because the PropertyStorage should have been created when applying the style.
                            INTERNAL_PropertyStore.SetLocalStyleValue(storage, newSetter.Value);
                        }
                    }

                    // Tell the setter which Style it belongs to, so that when the Value of the Setter changes, it can notify the parent Style:
                    newSetter.INTERNAL_ParentStyle = newStyle;
                }
            }
        }
        static void DetachVisualChidrenRecursively(UIElement element)
        {
            // Debug:
            //System.Diagnostics.Debug.WriteLine("Detached: " + element.GetType().Name);


            if (element._pointerExitedEventManager != null)
            {
                //todo: use element.INTERNAL_IsPointerInside for the test then set it to false.
                //bool wasPointerInElement = Convert.ToBoolean(CSHTML5.Interop.ExecuteJavaScript("$0.data_IsMouseInside", element.INTERNAL_OuterDomElement));
                //if (wasPointerInElement)
                if (element.INTERNAL_isPointerInside)
                {
#if MIGRATION
                    //element.ProcessOnMouseLeave(CSHTML5.Interop.ExecuteJavaScript("window.lastPointerPosition.event"));
                    MouseEventArgs eventArgs = new MouseEventArgs();
                    element.OnMouseLeave(eventArgs);
                    element.OnMouseLeave_ForHandledEventsToo(eventArgs);
#else
                    PointerRoutedEventArgs eventArgs = new PointerRoutedEventArgs();
                    element.OnPointerExited(eventArgs);//CSHTML5.Interop.ExecuteJavaScript("window.lastPointerPosition.event"));
                    element.OnPointerExited_ForHandledEventsToo(eventArgs);
#endif
                }
                element.isAlreadySubscribedToMouseEnterAndLeave = false;
                element.INTERNAL_isPointerInside = false;
            }

            // Call the "OnDetached" of the element. This is particularly useful for elements to clear any references they have to DOM elements. For example, the Grid will use it to set its _tableDiv to null.
            element.INTERNAL_OnDetachedFromVisualTree();

            //We detach the events from the dom element:
            element.INTERNAL_DetachFromDomEvents();

            // Call the "Unloaded" event: (note: in XAML, the "unloaded" event of the parent is called before the "unloaded" event of the children)
            element._isLoaded = false;
            if (element is FrameworkElement)
            {
                ((FrameworkElement)element).INTERNAL_RaiseUnloadedEvent();
            }

            // Traverse all elements recursively:
            if (element.INTERNAL_VisualChildrenInformation != null)
            {
                foreach (INTERNAL_VisualChildInformation childInfo in
#if BRIDGE
                         INTERNAL_BridgeWorkarounds.GetDictionaryValues_SimulatorCompatible(element.INTERNAL_VisualChildrenInformation)
#else
                         element.INTERNAL_VisualChildrenInformation.Values
#endif
                         )
                {
                    DetachVisualChidrenRecursively(childInfo.INTERNAL_UIElement);
                }
            }

            DependencyObject oldParent = element.INTERNAL_VisualParent;

            // Reset all visual-tree related information:
            element.INTERNAL_OuterDomElement                            = null;
            element.INTERNAL_InnerDomElement                            = null;
            element.INTERNAL_VisualParent                               = null;
            element.INTERNAL_VisualChildrenInformation                  = null;
            element.INTERNAL_AdditionalOutsideDivForMargins             = null;
            element.INTERNAL_DeferredRenderingWhenControlBecomesVisible = null;
            element.INTERNAL_DeferredLoadingWhenControlBecomesVisible   = null;

            // We reset the inherited properties since the element is no longer attached to its parent
            element.ResetInheritedProperties();

            if (oldParent != null)
            {
                UIElement.SynchronizeForceInheritProperties(element, oldParent);
            }
        }
Exemplo n.º 24
0
        internal static object INTERNAL_ConvertFromString(string colorString)
        {
            string trimmedString = colorString.Trim();

            if (!string.IsNullOrEmpty(trimmedString) && (trimmedString[0] == '#'))
            {
                string tokens = trimmedString.Substring(1);
                if (tokens.Length == 6) // This is becaue XAML is tolerant when the user has forgot the alpha channel (eg. #DDDDDD for Gray).
                {
                    tokens = "FF" + tokens;
                }

#if NETSTANDARD
                int color;
                if (int.TryParse(tokens, NumberStyles.HexNumber, NumberFormatInfo.CurrentInfo, out color))
                {
                    return(INTERNAL_ConvertFromInt32(color));
                }
#else // BRIDGE
                int color;
                if (CSHTML5.Interop.IsRunningInTheSimulator)
                {
                    color = INTERNAL_BridgeWorkarounds.HexToInt_SimulatorOnly(tokens);
                }
                else
                {
                    color = Script.Write <int>("parseInt({0}, 16);", tokens);
                }

                return(INTERNAL_ConvertFromInt32(color));
#endif
            }
            else if (trimmedString != null && trimmedString.StartsWith("sc#", StringComparison.Ordinal))
            {
                string tokens = trimmedString.Substring(3);

                char[] separators = new char[1] {
                    ','
                };
                string[] words  = tokens.Split(separators);
                float[]  values = new float[4];
                for (int i = 0; i < 3; i++)
                {
                    values[i] = Convert.ToSingle(words[i]);
                }
                if (words.Length == 4)
                {
                    values[3] = Convert.ToSingle(words[3]);
                    return(Color.FromScRgb(values[0], values[1], values[2], values[3]));
                }
                else
                {
                    return(Color.FromScRgb(1.0f, values[0], values[1], values[2]));
                }
            }
            else
            {
                // Check if the color is a named color
                Colors.INTERNAL_ColorsEnum namedColor;
                if (Enum.TryParse(trimmedString, true, out namedColor))
                {
                    return(INTERNAL_ConvertFromInt32((int)namedColor));
                }
            }
            throw new Exception(string.Format("Invalid color: {0}", colorString));
        }