Рисование соединительных линий на многоуровневой древовидной диаграммеC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Рисование соединительных линий на многоуровневой древовидной диаграмме

Сообщение Anonymous »

Я пытаюсь построить многоуровневую древовидную диаграмму с соединителями между ними, где у вас может быть неопределенное количество ответвлений узлов.
На данный момент я основывал свое решение в разделе «рисование линии» этого ответа: https://stackoverflow.com/a/2824595/6691231, но у меня возникли проблемы с отображением соединителей на каждом уровне. Вот результат, который я получаю для своего кода:
Изображение

который, как вы можете видеть, показывает соединители только на первом дочернем уровне, а не на втором. Я попытался добавить все соединители на один холст, но тогда ничего не отображалось. Кто-нибудь может помочь?
Код для рисования пользовательского интерфейса цепочки:
```private void DrawChain(List itemList)
{
items = new ObservableCollection();

Canvas connectorCanvas = new Canvas() { HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Stretch };

mainGrid = new Grid();
mainGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
mainGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
mainGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
//connectorCanvas.Children.Add(mainGrid);

// Set buyer links
Dictionary childDict = itemList.GroupBy(i => i.ParentCode).ToDictionary(i => i.Key, i => i.ToList());
Dictionary parentDict = itemList.GroupBy(i => i.ChildCode).ToDictionary(i => i.Key, i => i.ToList());

ChainLink ourLink = new ChainLink(currentLinkObj, connectorCanvas);
mainGrid.Children.Add(ourLink);
Grid.SetRow(ourLink, 1);

StackPanel childrenVerticalPanel = new StackPanel() { Orientation = Orientation.Vertical };
mainGrid.Children.Add(childrenVerticalPanel);
Grid.SetRow(childrenVerticalPanel, 2);
DrawChildren(ourLink, childrenVerticalPanel, connectorCanvas, childDict, false);
}

private void DrawChildren(ChainLink parentLinkItem, StackPanel parentPanel, Canvas connectorCanvas, Dictionary itemDict, bool reverseConnector)
{
StackPanel chainLinkPanel = new StackPanel() { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Center };

parentPanel.Children.Add(connectorCanvas);
parentPanel.Children.Add(chainLinkPanel);

if (itemDict.TryGetValue(parentLinkItem.Offer.Code, out List children))
{
foreach (ChainItem child in children)
{
object linkObj = chain.FirstOrDefault(o => o.Code == child.ChildCode);
if (linkObj != null)
{
ChainLink childLink = new ChainLink(linkObj, connectorCanvas) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top };

ChainConnector connector = new ChainConnector(reverseConnector) { Height = 35, HorizontalAlignment = HorizontalAlignment.Left };
connector.SetBinding(ChainConnector.SourceProperty, new Binding("AnchorPoint") { Source = parentLinkItem });
connector.SetBinding(ChainConnector.DestinationProperty, new Binding("AnchorPoint") { Source = childLink });

connectorCanvas.Children.Add(connector);

if (itemDict.TryGetValue(linkObj.Code, out _))
{
StackPanel verticalPanel = new StackPanel() { Orientation = Orientation.Vertical };
chainLinkPanel.Children.Add(verticalPanel);
verticalPanel.Children.Add(childLink);
Canvas childCanvas = new Canvas() { HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top };
DrawChildren(childLink, verticalPanel, childCanvas, itemDict, reverseConnector);
}
else
{
chainLinkPanel.Children.Add(childLink);
}
}
}
}
}```

Объедините элемент с помощью метода LayoutUpdated:
```public ChainLink(object linkObj, Canvas canvas)
{
this.linkObj= linkObj;
this.canvas = canvas;
LayoutUpdated += OnLayoutUpdated;
InitializeComponent();
}

private void OnLayoutUpdated(object sender, EventArgs e)
{
if (IsLoaded)
{
try
{
Size size = RenderSize;
Point ofs = new Point(size.Width / 2, size.Height);
AnchorPoint = TransformToVisual(canvas).Transform(ofs);
}
catch (Exception ex)
{
// Do nothing yet
}
}
}```

Код разъема:
```public partial class ChainConnector : UserControl
{
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(Point), typeof(ChainConnector), new FrameworkPropertyMetadata(default(Point)));
public static readonly DependencyProperty DestinationProperty = DependencyProperty.Register("Destination", typeof(Point), typeof(ChainConnector), new FrameworkPropertyMetadata(default(Point)));
private bool reverseDirection;

public Point Source
{
get { return (Point)this.GetValue(SourceProperty); }
set { this.SetValue(SourceProperty, value); }
}

public Point Destination
{
get { return (Point)this.GetValue(DestinationProperty); }
set { this.SetValue(DestinationProperty, value); }
}

public ChainConnector(bool reverseDirection)
{
LineSegment segment = new LineSegment(default(Point), true);
PathFigure figure = new PathFigure(default(Point), new[] { segment }, false);
PathGeometry geometry = new PathGeometry(new[] { figure });
BindingBase sourceBinding = new Binding { Source = this, Path = new PropertyPath(SourceProperty) };
BindingBase destinationBinding = new Binding { Source = this, Path = new PropertyPath(DestinationProperty) };

if (!reverseDirection)
{
BindingOperations.SetBinding(figure, PathFigure.StartPointProperty, sourceBinding);
BindingOperations.SetBinding(segment, LineSegment.PointProperty, destinationBinding);
}
else
{
BindingOperations.SetBinding(figure, PathFigure.StartPointProperty, destinationBinding);
BindingOperations.SetBinding(segment, LineSegment.PointProperty, sourceBinding);
}

Content = new Path
{
Data = geometry,
StrokeThickness = 1,
Stroke = Brushes.Black,
MinWidth = 1,
MinHeight = 1
};
}
}```


Подробнее здесь: https://stackoverflow.com/questions/787 ... ee-diagram
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Добавление соединительных строк между элементами списка с использованием CSS
    Anonymous » » в форуме CSS
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Не в состоянии сделать стержни в горизонтальном диаграмме в диаграмме.
    Anonymous » » в форуме Javascript
    0 Ответы
    37 Просмотры
    Последнее сообщение Anonymous
  • Blazor Webassembly Рисование интерактивных линий с использованием Svg
    Anonymous » » в форуме C#
    0 Ответы
    24 Просмотры
    Последнее сообщение Anonymous
  • Blazor Webassembly Рисование интерактивных линий с использованием Svg
    Anonymous » » в форуме C#
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous
  • Рисование линий в файлах .xlsx с помощью C# (предпочтительно OpenXml)
    Anonymous » » в форуме C#
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»