/// <summary> /// Get the final size Rect of a child element. /// </summary> /// <param name="element">The element to measure.</param> /// <returns>The calculated size Rect.</returns> private Rect GetFinalRect(FrameworkElement element) { double top = FlowGrid.GetTop(element); double bottom = FlowGrid.GetBottom(element); double left = FlowGrid.GetLeft(element); double right = FlowGrid.GetRight(element); return(new Rect(left, top, right - left, bottom - top)); }
/// <summary> /// Arrange the child elements in the parent grid based on the virtual FlowGrid column and row arrangement. /// </summary> /// <param name="size">The size available to the control.</param> private void ArrangeItems(Size size) { List <FlowGridRow> rows = new List <FlowGridRow>(this.Children); // columnStop is essentially the horizontal offset for a vertical set of rows. double columnStop = 0.0; Visibility visibility = System.Windows.Visibility.Visible; while (rows.Count > 0 && columnStop < size.Width) { // The column is literally the column of rows we're going to layout at this columnStop in the vertical space we have. List <FlowGridRow> column = this.GetColumn(rows, size.Height); double height = 0.0; double[] widths = new double[this.ColumnDefinitions.Count + 1]; double totalWidth = 0; // Calculate how big everything in the column is. foreach (FlowGridRow row in column) { for (int element = 0; element < row.Count && element < this.ColumnDefinitions.Count; ++element) { double width = row.ColumnWidth(element); if (widths[element + 1] < width) { widths[element + 1] = width; } } } // Tally up the width of the column. foreach (double width in widths) { totalWidth += width; } // If the column won't fit in the available space, it, and everything after it, shouldn't get displayed. if (columnStop + totalWidth >= size.Width) { visibility = System.Windows.Visibility.Collapsed; } // Afix each of the elements in the column to their the correct places on the canvas. foreach (FlowGridRow row in column) { for (int element = 0; element < row.Count && element < this.ColumnDefinitions.Count; ++element) { FlowGrid.SetLeft(row[element], GetLeft(row[element], columnStop + widths[element], widths[element + 1])); FlowGrid.SetTop(row[element], GetTop(row[element], height, row.Height)); row[element].Visibility = visibility; } height += row.Height; } columnStop += totalWidth; } // Any rows left over couldn't be placed for some reason or another, so they shouldn't be displayed at all. foreach (FlowGridRow row in rows) { foreach (FrameworkElement element in row.VisualCells) { element.Visibility = System.Windows.Visibility.Collapsed; } } }
/// <summary> /// Initialize a new status bar. /// </summary> public StatusBar() { ControlTemplate template = new ControlTemplate(); FrameworkElementFactory templateGrid = new FrameworkElementFactory(typeof(Grid)); LinearGradientBrush backgroundBrush = new LinearGradientBrush() { StartPoint = new Point(0.0, 0.5), EndPoint = new Point(1.0, 0.5) }; FrameworkElementFactory itemPresenter = new FrameworkElementFactory(typeof(ItemsPresenter)); StatusBarItem imageItem = new StatusBarItem(); Image image = new Image(); Border imageBorder = new Border() { MaxHeight = 248, MaxWidth = 248, MinHeight = 40, MinWidth = 40, Margin = new Thickness(1, 0, 0, 0) }; StatusBarItem flowItem = new StatusBarItem() { HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch, HorizontalContentAlignment = System.Windows.HorizontalAlignment.Stretch, VerticalAlignment = System.Windows.VerticalAlignment.Stretch, Margin = new Thickness(0, 4, 0, 0) }; Image ribbon = new Image() { HorizontalAlignment = System.Windows.HorizontalAlignment.Right, Source = new BitmapImage(new Uri(@"..\Resources\Ribbon.png", UriKind.Relative)) }; Grid panel = new Grid(); // Set the visual template for the status bar. backgroundBrush.GradientStops.Add(new GradientStop() { Color = Color.FromRgb(0xF3, 0xFB, 0xFE), Offset = 0.0 }); backgroundBrush.GradientStops.Add(new GradientStop() { Color = Color.FromRgb(0xF1, 0xFB, 0xFE), Offset = 0.25 }); backgroundBrush.GradientStops.Add(new GradientStop() { Color = Color.FromRgb(0xEE, 0xFB, 0xFE), Offset = 0.5 }); backgroundBrush.GradientStops.Add(new GradientStop() { Color = Color.FromRgb(0xEB, 0xFA, 0xFD), Offset = 0.75 }); backgroundBrush.GradientStops.Add(new GradientStop() { Color = Color.FromRgb(0xBB, 0xD9, 0xF0), Offset = 1.0 }); templateGrid.AppendChild(itemPresenter); templateGrid.SetValue(Control.BackgroundProperty, backgroundBrush); template.VisualTree = templateGrid; base.Template = template; // Add the icon. image.SetBinding(Image.SourceProperty, new Binding("Icon") { Source = this }); imageBorder.Child = image; //imageBorder.Padding = new Thickness(0, 0, 3, 0); imageItem.Content = imageBorder; imageItem.Margin = new Thickness(0, 0, 0, -1); base.AddChild(imageItem); panel.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(300, GridUnitType.Star) }); panel.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto }); // Build the flow grid where all the information goes. this.flowGrid = new FlowGrid() { HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch, VerticalAlignment = System.Windows.VerticalAlignment.Stretch, Margin = new Thickness(1, 0, 0, 10), SnapsToDevicePixels = true }; this.flowGrid.SetValue(Grid.ColumnProperty, 0); this.flowGrid.ColumnDefinitions.Add(new ColumnDefinition()); this.flowGrid.ColumnDefinitions.Add(new ColumnDefinition() { MinWidth = 80 }); this.flowGrid.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; panel.Children.Add(this.flowGrid); // Build the ribbon/Extra area. ribbon.SetValue(Panel.ZIndexProperty, -1); ribbon.SetValue(Grid.ColumnSpanProperty, 2); ribbon.SetValue(Grid.ColumnProperty, 0); panel.Children.Add(ribbon); this.parentGrid = new Grid(); this.parentGrid.HorizontalAlignment = System.Windows.HorizontalAlignment.Right; this.parentGrid.SetValue(Grid.ColumnProperty, 1); panel.Children.Add(this.parentGrid); flowItem.Content = panel; base.AddChild(flowItem); this.Children = this.flowGrid.Children; }