簡體   English   中英

在WPF畫布上分層繪制矩形

[英]Drawing hierarchically Rectangle on WPF Canvas

我正在嘗試像下一張圖片一樣放置rectangles

在此處輸入圖片說明

藍色箭頭顯示來自childparent-element

我有一個名為Box的類,其中有Box的父屬性。 我將所有創建的Box放入XAML代碼中用於綁定的ObservableCollection中。

這是Box類:

public class Box
{
    public string Content { get; set; } //Content in the Box
    public double X { get; set; }       //For Canvas.Left propertie
    public double Y { get; set; }       //For Canvas.Right propertie
    public double Width { get; set; }
    public double Height { get; set; }
    public Box Parent { get; set; }
}

但是現在我沒有正確的方法在畫布上繪制矩形,如圖所示。 我想到了創建具有不同列數的網格的想法,但是我不確定是否有可能。

最好的祝福。

如果僅出於布局目的在畫布中繪制矩形,則可以利用WPF的面板輕松得多。 要將完整的綁定與ObservableCollection結合使用,需要進行大量編碼。 因此,以下是一個簡單的示例。

箱類

public class Box
{
  public int Id { get; private set; }
  public int ParentId { get; private set; }
  public string Content { get; private set; }

  public Box(string content, int id, int parentId)
  {
    this.Id = id;
    this.ParentId = parentId;
    this.Content = content;
  }
}

從StackPanel繼承的BoxPanel類

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

public class BoxPanel : StackPanel
{
  public int Id { get; private set; }

  private readonly Border topPanel;
  private readonly StackPanel bottomPanel;

  public BoxPanel()
  {
    topPanel = new Border();
    bottomPanel = new StackPanel { Orientation = Orientation.Horizontal };

    this.Children.Add(topPanel);
    this.Children.Add(bottomPanel);
  }

  public BoxPanel(Box box)
    : this()
  {
    Id = box.Id;

    topPanel.Child = new TextBlock
    {
      Text = box.Content,
      HorizontalAlignment = HorizontalAlignment.Center,
      VerticalAlignment = VerticalAlignment.Center,
      Padding = new Thickness(14),
      Foreground = Brushes.White,
    };
    topPanel.Background = (Id % 2 == 0) ? Brushes.Gray : Brushes.DarkGray;
    topPanel.BorderBrush = Brushes.Black;
    topPanel.BorderThickness = new Thickness(1);
  }

  protected override void OnInitialized(EventArgs e)
  {
    base.OnInitialized(e);

    this.Loaded += (_, __) => AdjustBottomPanel();
    this.LayoutUpdated += (_, __) => AdjustBottomPanel();
  }

  public IReadOnlyCollection<BoxPanel> ChildrenPanel
  {
    get { return bottomPanel.Children.Cast<BoxPanel>().ToArray(); }
  }

  public void AddChildPanel(BoxPanel child)
  {
    bottomPanel.Children.Add(child);
    AdjustBottomPanel();
  }

  private void AdjustBottomPanel()
  {
    if (!ChildrenPanel.Any())
      return;

    var childWidth = Math.Max((Double.IsNaN(this.Width) ? 0 : this.Width), this.ActualWidth)
      / ChildrenPanel.Count;

    foreach (var child in ChildrenPanel)
      child.Width = childWidth;
  }
}

MainWindow的XAML

<Window x:Class="WpfBoxPanel.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Width="500" Height="240">
  <Grid x:Name="LayoutRoot"/>
</Window>

和MainWindow后面的代碼

using System.Collections.Generic;
using System.Linq;
using System.Windows;

public partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();

    boxPanelRoot = new BoxPanel();
    LayoutRoot.Children.Add(boxPanelRoot);

    this.Loaded += (_, __) => PopulateBoxPanel();
  }

  private readonly IList<Box> Boxes = new List<Box>
  {
    new Box("1st", 1, 0),
    new Box("2nd 1", 2, 1),
    new Box("2nd 2", 3, 1),
    new Box("3rd 1", 4, 2),
    new Box("3rd 2", 5, 2),
    new Box("3rd 3", 6, 3),
    new Box("4th 1", 7, 4),
    new Box("4th 2", 8, 5),
    new Box("4th 3", 9, 5),
    new Box("4th 4", 10, 6),
    new Box("4th 5", 11, 6),
  };

  private readonly BoxPanel boxPanelRoot;

  private void PopulateBoxPanel()
  {
    foreach (var box in Boxes)
    {
      var existingPanels = boxPanelRoot.GetDescendants() // See VisualTreeHelperExtensions.GetDescendants method of WinRT Xaml Toolkit
        .OfType<BoxPanel>()
        .ToArray();

      if (existingPanels.Any(x => x.Id == box.Id))
        continue;

      var parent = existingPanels.FirstOrDefault(x => x.Id == box.ParentId);
      if (parent == null)
        parent = boxPanelRoot;

      parent.AddChildPanel(new BoxPanel(box));
    }
  }
}

WpfBoxPanel屏幕截圖

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM