Exemple #1
0
        /// <summary>
        /// Provides base class initialization behavior for Shape derived classes.
        /// </summary>
        protected Shape()
        {
            SizeChanged += Shape_SizeChanged;

            // Fix the issue with Grid implemented using html <table>, which is unable to force the size of its children:
            if (!Grid_InternalHelpers.isCSSGridSupported())
            {
                Window.Current.SizeChanged += Current_SizeChanged; //this is to make sure that the canvas does not block redimensionning when changing the window size.
                // Note: this still does not solve the issue we have when shrinking a parent element of the shape when the shape is stretched.
                // To reproduce the issue:
                // <Grid Width="300">
                //   <Rectangle Width="Auto" Stretch="Fill"/>
                // </Grid>
                // Then, after this has been drawn, programmatically reduce the size of the border => the rectangle will not become smaller because
                // its inner html <canvas> has a fixed size and prevents its container from being smaller.
            }

            IsVisibleChanged += (d, e) =>
            {
                bool newValue = (bool)e.NewValue;
                if (newValue && _redrawWhenBecomeVisible)
                {
                    ScheduleRedraw();
                }
            };
        }
Exemple #2
0
        /// <summary>
        /// Set the DOM element that will host the window. This can be set only to new windows. The MainWindow looks for a DIV that has the ID "cshtml5-root".
        /// </summary>
        /// <param name="rootDomElement">The DOM element that will host the window</param>
        public void AttachToDomElement(object rootDomElement)
        {
            if (this.INTERNAL_OuterDomElement != null ||
                this.INTERNAL_RootDomElement != null)
            {
                throw new InvalidOperationException("The method 'Window.AttachToDomElement' can be called only once.");
            }

            if (rootDomElement == null)
            {
                throw new ArgumentNullException("rootDomElement");
            }

            //Note: The "rootDomElement" will contain one DIV for the root of the window visual tree, and other DIVs to host the popups.
            this.INTERNAL_RootDomElement = rootDomElement;

            // Reset the content of the root DIV:
            Interop.ExecuteJavaScriptAsync(@"$0.innerHTML = ''", rootDomElement);

            // In case of XAML view hosted inside an HTML app, we usually set the "position" of the window root to "relative" rather than "absolute" (via external JavaScript code) in order to display it inside a specific DIV. However, in this case, the layers that contain the Popups are placed under the window DIV instead of over it. To work around this issue, we set the root element display to "grid". See the sample app "IntegratingACshtml5AppInAnSPA".
            if (Grid_InternalHelpers.isCSSGridSupported()) //todo: what about the old browsers where "CSS Grid" is not supported?
            {
                Interop.ExecuteJavaScriptAsync("$0.style.display = 'grid'", rootDomElement);
            }

            // Create the DIV that will correspond to the root of the window visual tree:
            object windowRootDiv;

#if CSHTML5NETSTANDARD
            INTERNAL_HtmlDomStyleReference
#else
            dynamic
#endif
            windowRootDivStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", rootDomElement, this, out windowRootDiv);

            windowRootDivStyle.position  = "absolute";
            windowRootDivStyle.width     = "100%";
            windowRootDivStyle.height    = "100%";
            windowRootDivStyle.overflowX = "hidden";
            windowRootDivStyle.overflowY = "hidden";

            this.INTERNAL_OuterDomElement = windowRootDiv;
            this.INTERNAL_InnerDomElement = windowRootDiv;

            // Set the window as "loaded":
            this._isLoaded = true;

            // Attach the window content, if any:
            object content = this.Content;
            if (content != null)
            {
                OnContentChanged(null, content);
            }

            // Raise the "Loaded" event:
            this.INTERNAL_RaiseLoadedEvent();
        }
Exemple #3
0
        private static void HeaderTemplate_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridRow dataGridRow = (DataGridRow)d;

            if (dataGridRow != null)
            {
                if (INTERNAL_VisualTreeManager.IsElementInVisualTree(dataGridRow._datagrid))
                {
                    if (e.NewValue != e.OldValue)
                    {
                        if (dataGridRow._headerUIElement != null && INTERNAL_VisualTreeManager.IsElementInVisualTree(dataGridRow._headerUIElement))
                        {
                            //we remove the header that was there before the new one:
                            dataGridRow._datagrid.RemoveElementFromGrid(dataGridRow._headerUIElement);
                        }
                        //we add the new header
                        DataTemplate template = (DataTemplate)e.NewValue;
                        if (template != null)
                        {
                            dataGridRow._headerUIElement = template.INTERNAL_InstantiateFrameworkTemplate();
                            Grid.SetRow(dataGridRow._headerUIElement, dataGridRow._rowIndex);
                            Grid.SetColumn(dataGridRow._headerUIElement, 0);
                            if (dataGridRow._headerUIElement is FrameworkElement)
                            {
                                ((FrameworkElement)dataGridRow._headerUIElement).DataContext = dataGridRow;
                            }
                            bool isCSSGrid = Grid_InternalHelpers.isCSSGridSupported();
                            if (isCSSGrid)
                            {
                                if (dataGridRow._headerUIElement is Control)
                                {
                                    ((Control)dataGridRow._headerUIElement).BorderBrush     = dataGridRow._datagrid.HorizontalGridLinesBrush;
                                    ((Control)dataGridRow._headerUIElement).BorderThickness = new Thickness(1, 0, 1, 1);
                                }
                                else if (dataGridRow._headerUIElement is Border)
                                {
                                    ((Border)dataGridRow._headerUIElement).BorderBrush     = dataGridRow._datagrid.HorizontalGridLinesBrush;
                                    ((Border)dataGridRow._headerUIElement).BorderThickness = new Thickness(1, 0, 1, 1);
                                }
                            }
                            dataGridRow._datagrid.AddElementToGrid(dataGridRow._headerUIElement);
                        }
                    }
                }
            }
        }
        private static void Width_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var columnDefinition = (ColumnDefinition)d;

            Grid grid = columnDefinition.Parent;

            if (grid != null &&
                INTERNAL_VisualTreeManager.IsElementInVisualTree(grid))
            {
                if (Grid_InternalHelpers.isCSSGridSupported())
                {
                    //-------------
                    // CSS Grid
                    //-------------

                    // We refresh all the columns:
                    Grid_InternalHelpers.RefreshAllColumnsWidth_CSSVersion(grid);
                }
                else
                {
                    //-------------
                    // Non-CSS Grid
                    //-------------

                    bool isStar = (e.OldValue != null && ((GridLength)e.OldValue).IsStar) || (e.NewValue != null && ((GridLength)e.NewValue).IsStar);
                    if (isStar)
                    {
                        // If we are dealing with a "Star" column, we need to refresh all the columns (because of the need to recalculate percentages normalization etc.):
                        Grid_InternalHelpers.RefreshAllColumnsWidth_NonCSSVersion(grid);
                    }
                    else
                    {
                        // Only refresh the current column:
                        if (grid._columnDefinitionsOrNull != null)
                        {
                            int  columnIndex     = grid._columnDefinitionsOrNull.IndexOf(columnDefinition);
                            bool isTheOnlyColumn = grid._columnDefinitionsOrNull == null || grid._columnDefinitionsOrNull.Count < 2;
                            Grid_InternalHelpers.RefreshColumnWidth_NonCSSVersion(grid, columnIndex, isTheOnlyColumn); //Note: we do not need to pass the normalized column definition because this method will only be called when we change the column's width without any star measurement involved (nor star before nor after).
                        }
                    }
                }
            }

            columnDefinition.Parent?.InvalidateMeasure();
        }
Exemple #5
0
        static void Height_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var  rowDefinition = (RowDefinition)d;
            Grid grid          = rowDefinition.Parent;

            if (grid != null &&
                INTERNAL_VisualTreeManager.IsElementInVisualTree(grid))
            {
                if (Grid_InternalHelpers.isCSSGridSupported())
                {
                    //-------------
                    // CSS Grid
                    //-------------

                    // We refresh all the rows:
                    Grid_InternalHelpers.RefreshAllRowsHeight_CSSVersion(grid);
                }
                else
                {
                    //-------------
                    // Non-CSS Grid
                    //-------------

                    bool isStar = (e.OldValue != null && ((GridLength)e.OldValue).IsStar) || (e.NewValue != null && ((GridLength)e.NewValue).IsStar);
                    if (isStar)
                    {
                        // If we are dealing with a "Star" row, we need to refresh all the rows (because of the need to recalculate percentages normalization etc.):
                        Grid_InternalHelpers.RefreshAllRowsHeight_NonCSSVersion(grid);
                    }
                    else
                    {
                        // Only refresh the current row:
                        if (grid._columnDefinitionsOrNull != null)
                        {
                            int  rowIndex     = grid._rowDefinitionsOrNull.IndexOf(rowDefinition);
                            bool isTheOnlyRow = grid._columnDefinitionsOrNull == null || grid._columnDefinitionsOrNull.Count < 2;
                            Grid_InternalHelpers.RefreshRowHeight_NonCSSVersion(grid, rowIndex, isTheOnlyRow); // Note: we do not need to pass the normalized row definition because this method will only be called when we change the row's height without any star measurement involved (nor star before nor after).
                        }
                    }
                }
            }
        }
Exemple #6
0
        static void ManageChildrenChanged(DependencyObject d, UIElementCollection oldChildren, UIElementCollection newChildren)
        {
#if PERFSTAT
            var t1 = Performance.now();
#endif

            Panel parent = (Panel)d;
            if (parent is DockPanel)
            {
                ((DockPanel)parent).ManageChildrenChanged(oldChildren, newChildren);
            }
            else
            {
                bool isCSSGrid = Grid_InternalHelpers.isCSSGridSupported();
                if (!isCSSGrid && parent is Grid)
                {
                    ((Grid)parent).ManageChildrenChanged(oldChildren, newChildren);
                }
                else
                {
                    if (oldChildren != null)
                    {
                        //// Put the list in a HashSet for performant lookup:
                        //HashSet<UIElement> newChidrenHashSet = new HashSet<UIElement>();
                        //if (newChildren != null)
                        //{
                        //    foreach (UIElement child in newChildren)
                        //        newChidrenHashSet.Add(child);
                        //}
                        //// Detach old children only if they are not in the "newChildren" collection:
                        //foreach (UIElement child in oldChildren)
                        //{
                        //    if (newChildren == null || !newChidrenHashSet.Contains(child)) //todo: verify that in the produced JavaScript, "newChidrenHashSet.Contains" has still a O(1) complexity.
                        //    {
                        //        INTERNAL_VisualTreeManager.DetachVisualChildIfNotNull(child, parent);
                        //    }
                        //}

                        //todo: use HashSet version.

                        // Detach old children only if they are not in the "newChildren" collection:
                        foreach (UIElement child in oldChildren) //note: there is no setter for Children so the user cannot change the order of the elements in one step --> we cannot have the same children in another order (which would keep the former order with the way it is handled now) --> no problem here
                        {
#if PERFSTAT
                            var t2 = Performance.now();
#endif
                            if (newChildren == null || !newChildren.Contains(child))
                            {
#if PERFSTAT
                                Performance.Counter("Panel.ManageChildrenChanged 'Contains'", t2);
#endif
                                INTERNAL_VisualTreeManager.DetachVisualChildIfNotNull(child, parent);
                            }
                            else
                            {
#if PERFSTAT
                                Performance.Counter("Panel.ManageChildrenChanged 'Contains'", t2);
#endif
                            }
                        }
                    }
                    if (newChildren != null)
                    {
                        foreach (UIElement child in newChildren)
                        {
                            // Note: we do this for all items (regardless of whether they are in the oldChildren collection or not) to make it work when the item is first added to the Visual Tree (at that moment, all the properties are refreshed by calling their "Changed" method).
                            INTERNAL_VisualTreeManager.AttachVisualChildIfNotAlreadyAttached(child, parent);
                        }
                    }

                    if (parent is Grid)
                    {
                        ((Grid)parent).LocallyManageChildrenChanged();
                    }
                }
            }
        }