Exemplo n.º 1
0
        protected override Size ArrangeOverride(Size finalSize)
        {
            bool has_row_definitions    = row_definitions.Count != 0;
            bool has_column_definitions = column_definitions.Count != 0;

            if ((has_row_definitions || has_column_definitions) && !measure_called)
            {
                throw new NullReferenceException();
            }
            int row_count    = GetRowColumnCount(row_definitions.Count);
            int column_count = GetRowColumnCount(column_definitions.Count);

            double [] row_heights   = new double [row_count];
            double [] column_widths = new double [column_count];
            int       index;

            #region Compute initial row and column size
            if (has_row_definitions)
            {
                for (index = 0; index < row_count; index++)
                {
                    GridLength row_definition_height = row_definitions [index].Height;
                    row_heights [index] = row_definition_height.IsAbsolute ? row_definition_height.Value : double.PositiveInfinity;
                }
            }
            else
            {
                row_heights [0] = finalSize.Height;
            }
            if (has_column_definitions)
            {
                for (index = 0; index < column_count; index++)
                {
                    GridLength column_definition_width = column_definitions [index].Width;
                    column_widths [index] = column_definition_width.IsAbsolute ? column_definition_width.Value : double.PositiveInfinity;
                }
            }
            else
            {
                column_widths [0] = finalSize.Width;
            }
            #endregion
            if (has_row_definitions || has_column_definitions)
            {
                double [] desired_row_heights   = new double [row_count];
                double [] desired_column_widths = new double [column_count];
                foreach (UIElement child in InternalChildren)
                {
                    if (has_row_definitions)
                    {
                        int child_row = Math.Min(GetRow(child), row_count - 1);
                        if (!row_definitions [child_row].Height.IsAbsolute && GetRowSpan(child) == 1)
                        {
                            desired_row_heights [child_row] = Math.Max(desired_row_heights [child_row], child.DesiredSize.Height);
                        }
                    }
                    if (has_column_definitions)
                    {
                        int child_column = Math.Min(GetColumn(child), column_count - 1);
                        if (!column_definitions [child_column].Width.IsAbsolute && GetColumnSpan(child) == 1)
                        {
                            desired_column_widths [child_column] = Math.Max(desired_column_widths [child_column], child.DesiredSize.Width);
                        }
                    }
                }
                if (has_row_definitions)
                {
                    for (index = 0; index < row_count; index++)
                    {
                        if (row_definitions [index].Height.IsAuto)
                        {
                            row_heights [index] = desired_row_heights [index];
                        }
                    }
                }
                if (has_column_definitions)
                {
                    for (index = 0; index < column_count; index++)
                    {
                        if (column_definitions [index].Width.IsAuto)
                        {
                            column_widths [index] = desired_column_widths [index];
                        }
                    }
                }
                #region Apply definition minimum and maximum
                if (has_row_definitions)
                {
                    for (index = 0; index < row_count; index++)
                    {
                        RowDefinition row_definition = row_definitions [index];
                        row_heights [index] = AdjustToBeInRange(row_heights [index], row_definition.MinHeight, row_definition.MaxHeight);
                    }
                }
                if (has_column_definitions)
                {
                    for (index = 0; index < column_count; index++)
                    {
                        ColumnDefinition column_definition = column_definitions [index];
                        column_widths [index] = AdjustToBeInRange(column_widths [index], column_definition.MinWidth, column_definition.MaxWidth);
                    }
                }
                #endregion
                #region Distribute remaining space to rows/columns with star size
                double  total_star;
                double  remaining_lenght;
                double  star_ratio;
                bool [] uses_star_sizing;
                bool    current_star_sizing_valid;
                if (has_row_definitions)
                {
                    uses_star_sizing = new bool [row_count];
                    for (index = 0; index < row_count; index++)
                    {
                        uses_star_sizing [index] = row_definitions [index].Height.IsStar;
                    }
                    do
                    {
                        current_star_sizing_valid = true;
                        total_star       = 0;
                        remaining_lenght = finalSize.Height;
                        for (index = 0; index < row_count; index++)
                        {
                            if (uses_star_sizing [index])
                            {
                                total_star += row_definitions [index].Height.Value;
                            }
                            else
                            {
                                remaining_lenght -= row_heights [index];
                            }
                        }
                        if (remaining_lenght > 0 && total_star != 0)
                        {
                            star_ratio = remaining_lenght / total_star;
                            for (index = 0; index < row_count; index++)
                            {
                                if (uses_star_sizing [index])
                                {
                                    RowDefinition definition      = row_definitions [index];
                                    double        proposed_lenght = Math.Max(definition.Height.Value * star_ratio, desired_row_heights [index]);
                                    if (proposed_lenght < definition.MinHeight)
                                    {
                                        row_heights [index]       = definition.MinHeight;
                                        uses_star_sizing [index]  = false;
                                        current_star_sizing_valid = false;
                                        break;
                                    }
                                    else if (proposed_lenght > definition.MaxHeight)
                                    {
                                        row_heights [index]       = definition.MaxHeight;
                                        uses_star_sizing [index]  = false;
                                        current_star_sizing_valid = false;
                                        break;
                                    }
                                    else
                                    {
                                        row_heights [index] = proposed_lenght;
                                    }
                                }
                            }
                        }
                    } while (!current_star_sizing_valid);
                }
                if (has_column_definitions)
                {
                    uses_star_sizing = new bool [column_count];
                    for (index = 0; index < column_count; index++)
                    {
                        uses_star_sizing [index] = column_definitions [index].Width.IsStar;
                    }
                    do
                    {
                        current_star_sizing_valid = true;
                        total_star       = 0;
                        remaining_lenght = finalSize.Width;
                        for (index = 0; index < column_count; index++)
                        {
                            if (uses_star_sizing [index])
                            {
                                total_star += column_definitions [index].Width.Value;
                            }
                            else
                            {
                                remaining_lenght -= column_widths [index];
                            }
                        }
                        if (remaining_lenght > 0 && total_star != 0)
                        {
                            star_ratio = remaining_lenght / total_star;
                            for (index = 0; index < column_count; index++)
                            {
                                if (uses_star_sizing [index])
                                {
                                    ColumnDefinition definition      = column_definitions [index];
                                    double           proposed_lenght = Math.Max(definition.Width.Value * star_ratio, desired_column_widths [index]);
                                    if (proposed_lenght < definition.MinWidth)
                                    {
                                        column_widths [index]     = definition.MinWidth;
                                        uses_star_sizing [index]  = false;
                                        current_star_sizing_valid = false;
                                        break;
                                    }
                                    else if (proposed_lenght > definition.MaxWidth)
                                    {
                                        column_widths [index]     = definition.MaxWidth;
                                        uses_star_sizing [index]  = false;
                                        current_star_sizing_valid = false;
                                        break;
                                    }
                                    else
                                    {
                                        column_widths [index] = proposed_lenght;
                                    }
                                }
                            }
                        }
                    } while (!current_star_sizing_valid);
                }
                #endregion
                #region Set row/column definitions ActualWidth/Height and Offset values
                double offset;
                if (has_row_definitions)
                {
                    remaining_lenght = finalSize.Height;
                    offset           = 0;
                    for (index = 0; index < row_count; index++)
                    {
                        if (row_heights [index] > remaining_lenght)
                        {
                            row_heights [index] = remaining_lenght;
                        }
                        remaining_lenght -= row_heights [index];
                        RowDefinition definition = row_definitions [index];
                        definition.Offset = offset;
                        offset           += definition.ActualHeight = row_heights [index];
                    }
                }
                if (has_column_definitions)
                {
                    remaining_lenght = finalSize.Width;
                    offset           = 0;
                    for (index = 0; index < column_count; index++)
                    {
                        if (column_widths [index] > remaining_lenght)
                        {
                            column_widths [index] = remaining_lenght;
                        }
                        remaining_lenght -= column_widths [index];
                        ColumnDefinition definition = column_definitions [index];
                        definition.Offset = offset;
                        offset           += definition.ActualWidth = column_widths [index];
                    }
                }
                #endregion
            }
            #region Arrange children
            foreach (UIElement child in InternalChildren)
            {
                Rect rect       = new Rect();
                int  row_column = Math.Min(GetRow(child), row_count - 1);
                for (index = 0; index < row_column; index++)
                {
                    rect.Y += row_heights [index];
                }
                int maximum = Math.Min(row_column + GetRowSpan(child), row_count);
                for (index = row_column; index < maximum; index++)
                {
                    rect.Height += row_heights [index];
                }
                row_column = Math.Min(GetColumn(child), column_count - 1);
                for (index = 0; index < row_column; index++)
                {
                    rect.X += column_widths [index];
                }
                maximum = Math.Min(row_column + GetColumnSpan(child), column_count);
                for (index = row_column; index < maximum; index++)
                {
                    rect.Width += column_widths [index];
                }
                child.Arrange(rect);
            }
            #endregion
            #region Create or update GridLinesRenderer
            if (grid_lines_renderer == null)
            {
                if (ShowGridLines && (has_row_definitions || has_column_definitions))
                {
                    grid_lines_renderer = new GridLinesRenderer(this);
                    AddVisualChild(grid_lines_renderer);
                    grid_lines_renderer.Rebuild();
                }
            }
            else
            {
                grid_lines_renderer.Rebuild();
            }
            #endregion
            return(finalSize);
        }
Exemplo n.º 2
0
        /// <summary> 
        /// Synchronized ShowGridLines property with the state of the grid's visual collection
        /// by adding / removing GridLinesRenderer visual.
        /// Returns a reference to GridLinesRenderer visual or null.
        /// </summary> 
        private GridLinesRenderer EnsureGridLinesRenderer()
        { 
            // 
            //  synchronize the state
            // 
            if (ShowGridLines && (_gridLinesRenderer == null))
            {
                _gridLinesRenderer = new GridLinesRenderer();
                this.AddVisualChild(_gridLinesRenderer); 
            }
 
            if ((!ShowGridLines) && (_gridLinesRenderer != null)) 
            {
                this.RemoveVisualChild(_gridLinesRenderer); 
                _gridLinesRenderer = null;
            }

            return (_gridLinesRenderer); 
        }
Exemplo n.º 3
0
		protected override Size ArrangeOverride (Size finalSize)
		{
			bool has_row_definitions = row_definitions.Count != 0;
			bool has_column_definitions = column_definitions.Count != 0;
			if ((has_row_definitions || has_column_definitions) && !measure_called)
				throw new NullReferenceException ();
			int row_count = GetRowColumnCount (row_definitions.Count);
			int column_count = GetRowColumnCount (column_definitions.Count);
			double [] row_heights = new double [row_count];
			double [] column_widths = new double [column_count];
			int index;
			#region Compute initial row and column size
			if (has_row_definitions)
				for (index = 0; index < row_count; index++) {
					GridLength row_definition_height = row_definitions [index].Height;
					row_heights [index] = row_definition_height.IsAbsolute ? row_definition_height.Value : double.PositiveInfinity;
				} else
				row_heights [0] = finalSize.Height;
			if (has_column_definitions)
				for (index = 0; index < column_count; index++) {
					GridLength column_definition_width = column_definitions [index].Width;
					column_widths [index] = column_definition_width.IsAbsolute ? column_definition_width.Value : double.PositiveInfinity;
				} else
				column_widths [0] = finalSize.Width;
			#endregion
			if (has_row_definitions || has_column_definitions) {
				double [] desired_row_heights = new double [row_count];
				double [] desired_column_widths = new double [column_count];
				foreach (UIElement child in InternalChildren) {
					if (has_row_definitions) {
						int child_row = Math.Min (GetRow (child), row_count - 1);
						if (!row_definitions [child_row].Height.IsAbsolute && GetRowSpan (child) == 1)
							desired_row_heights [child_row] = Math.Max (desired_row_heights [child_row], child.DesiredSize.Height);
					}
					if (has_column_definitions) {
						int child_column = Math.Min (GetColumn (child), column_count - 1);
						if (!column_definitions [child_column].Width.IsAbsolute && GetColumnSpan (child) == 1)
							desired_column_widths [child_column] = Math.Max (desired_column_widths [child_column], child.DesiredSize.Width);
					}
				}
				if (has_row_definitions)
					for (index = 0; index < row_count; index++)
						if (row_definitions [index].Height.IsAuto)
							row_heights [index] = desired_row_heights [index];
				if (has_column_definitions)
					for (index = 0; index < column_count; index++)
						if (column_definitions [index].Width.IsAuto)
							column_widths [index] = desired_column_widths [index];
				#region Apply definition minimum and maximum
				if (has_row_definitions)
					for (index = 0; index < row_count; index++) {
						RowDefinition row_definition = row_definitions [index];
						row_heights [index] = AdjustToBeInRange (row_heights [index], row_definition.MinHeight, row_definition.MaxHeight);
					}
				if (has_column_definitions)
					for (index = 0; index < column_count; index++) {
						ColumnDefinition column_definition = column_definitions [index];
						column_widths [index] = AdjustToBeInRange (column_widths [index], column_definition.MinWidth, column_definition.MaxWidth);
					}
				#endregion
				#region Distribute remaining space to rows/columns with star size
				double total_star;
				double remaining_lenght;
				double star_ratio;
				bool [] uses_star_sizing;
				bool current_star_sizing_valid;
				if (has_row_definitions) {
					uses_star_sizing = new bool [row_count];
					for (index = 0; index < row_count; index++)
						uses_star_sizing [index] = row_definitions [index].Height.IsStar;
					do {
						current_star_sizing_valid = true;
						total_star = 0;
						remaining_lenght = finalSize.Height;
						for (index = 0; index < row_count; index++) {
							if (uses_star_sizing [index])
								total_star += row_definitions [index].Height.Value;
							else
								remaining_lenght -= row_heights [index];
						}
						if (remaining_lenght > 0 && total_star != 0) {
							star_ratio = remaining_lenght / total_star;
							for (index = 0; index < row_count; index++)
								if (uses_star_sizing [index]) {
									RowDefinition definition = row_definitions [index];
									double proposed_lenght = Math.Max (definition.Height.Value * star_ratio, desired_row_heights [index]);
									if (proposed_lenght < definition.MinHeight) {
										row_heights [index] = definition.MinHeight;
										uses_star_sizing [index] = false;
										current_star_sizing_valid = false;
										break;
									} else if (proposed_lenght > definition.MaxHeight) {
										row_heights [index] = definition.MaxHeight;
										uses_star_sizing [index] = false;
										current_star_sizing_valid = false;
										break;
									} else
										row_heights [index] = proposed_lenght;
								}
						}
					} while (!current_star_sizing_valid);
				}
				if (has_column_definitions) {
					uses_star_sizing = new bool [column_count];
					for (index = 0; index < column_count; index++)
						uses_star_sizing [index] = column_definitions [index].Width.IsStar;
					do {
						current_star_sizing_valid = true;
						total_star = 0;
						remaining_lenght = finalSize.Width;
						for (index = 0; index < column_count; index++) {
							if (uses_star_sizing [index])
								total_star += column_definitions [index].Width.Value;
							else
								remaining_lenght -= column_widths [index];
						}
						if (remaining_lenght > 0 && total_star != 0) {
							star_ratio = remaining_lenght / total_star;
							for (index = 0; index < column_count; index++)
								if (uses_star_sizing [index]) {
									ColumnDefinition definition = column_definitions [index];
									double proposed_lenght = Math.Max (definition.Width.Value * star_ratio, desired_column_widths [index]);
									if (proposed_lenght < definition.MinWidth) {
										column_widths [index] = definition.MinWidth;
										uses_star_sizing [index] = false;
										current_star_sizing_valid = false;
										break;
									} else if (proposed_lenght > definition.MaxWidth) {
										column_widths [index] = definition.MaxWidth;
										uses_star_sizing [index] = false;
										current_star_sizing_valid = false;
										break;
									} else
										column_widths [index] = proposed_lenght;
								}
						}
					} while (!current_star_sizing_valid);
				}
				#endregion
				#region Set row/column definitions ActualWidth/Height and Offset values
				double offset;
				if (has_row_definitions) {
					remaining_lenght = finalSize.Height;
					offset = 0;
					for (index = 0; index < row_count; index++) {
						if (row_heights [index] > remaining_lenght)
							row_heights [index] = remaining_lenght;
						remaining_lenght -= row_heights [index];
						RowDefinition definition = row_definitions [index];
						definition.Offset = offset;
						offset += definition.ActualHeight = row_heights [index];
					}
				}
				if (has_column_definitions) {
					remaining_lenght = finalSize.Width;
					offset = 0;
					for (index = 0; index < column_count; index++) {
						if (column_widths [index] > remaining_lenght)
							column_widths [index] = remaining_lenght;
						remaining_lenght -= column_widths [index];
						ColumnDefinition definition = column_definitions [index];
						definition.Offset = offset;
						offset += definition.ActualWidth = column_widths [index];
					}
				}
				#endregion
			}
			#region Arrange children
			foreach (UIElement child in InternalChildren) {
				Rect rect = new Rect ();
				int row_column = Math.Min (GetRow (child), row_count - 1);
				for (index = 0; index < row_column; index++)
					rect.Y += row_heights [index];
				int maximum = Math.Min (row_column + GetRowSpan (child), row_count);
				for (index = row_column; index < maximum; index++)
					rect.Height += row_heights [index];
				row_column = Math.Min (GetColumn (child), column_count - 1);
				for (index = 0; index < row_column; index++)
					rect.X += column_widths [index];
				maximum = Math.Min (row_column + GetColumnSpan (child), column_count);
				for (index = row_column; index < maximum; index++)
					rect.Width += column_widths [index];
				child.Arrange (rect);
			}
			#endregion
			#region Create or update GridLinesRenderer
			if (grid_lines_renderer == null) {
				if (ShowGridLines && (has_row_definitions || has_column_definitions)) {
					grid_lines_renderer = new GridLinesRenderer (this);
					AddVisualChild (grid_lines_renderer);
					grid_lines_renderer.Rebuild ();
				}
			} else
				grid_lines_renderer.Rebuild ();
			#endregion
			return finalSize;
		}