ItemsControl项目位置问题

时间:2018-02-19 00:14:40

标签: c# wpf mvvm data-binding

简介

您好!

我正在创建自定义WPF UserControl以显示链接节点(特别是用于神经网络可视化)。我想通过数据绑定提供UserControl的对象源。

代码

XAML

<Grid Width="{Binding Width}" Height="{Binding Height}">
<StackPanel>
    <ItemsControl ItemsSource="{Binding Items}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <!-- Node container -->
                <Canvas Background="AliceBlue"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Left" Value="{Binding PosX}"/>
                <Setter Property="Canvas.Top" Value="{Binding PosY}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <!-- The Node -->
                    <Ellipse Width="{Binding Radius}" Height="{Binding Radius}" Fill="{Binding BackColor}" />
                    <!-- Node Links -->
                    <ItemsControl ItemsSource="{Binding Links}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Line Stroke="Black" StrokeThickness="2"
                                            ToolTip="{Binding Tooltip}" 
                                            X1="{Binding SourceX}"      Y1="{Binding SourceY}"
                                            X2="{Binding DestinationX}" Y2="{Binding DestinationY}"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</StackPanel> </Grid>

Csharp

public class StructureViewModel : BaseViewModel
{ 
    public double Width { get; set; } = 500;
    public double Height { get; set; } = 500;
    public List<Node> Items { get; set; }
    public Canvas SelectedShape { get; set; }

    public StructureViewModel()
    {
        Items = new List<Node>();

        var node1 = new Node(100, 150);
        var node2 = new Node(100, 180);
        node1.AddLink(node2);

        Items.Add(node1);
        Items.Add(node2);
    } 
}

public class Node : BaseViewModel
{
    public double Radius { get; set; } = 40;
    public Brush BackColor { get; set; } = Brushes.Blue;
    public double PosX { get; set; } = 0;
    public double PosY { get; set; } = 0;
    public List<Link> Links { get; set; }

    public Node(double posX, double posY)
    {
        Links = new List<Link>();
        PosX = posX;
        PosY = posY;
    }

    public Node(double posX, double posY, List<Link> links)
    {
        Links = links;
        PosX = posX;
        PosY = posY;
    }

    public void AddLink(Node node) => Links.Add(new Link(PosX, PosY, node.PosX, node.PosY)); 
}

public class Link : BaseViewModel
{
    public double SourceX { get; set; }
    public double SourceY { get; set; }
    public double DestinationX { get; set; }
    public double DestinationY { get; set; }
    public string ToolTip { get; set; }

    public Link(double x1, double y1, double x2, double y2, string tooltip = "")
    {
        SourceX = x1;
        SourceY = y1;
        DestinationX = x2;
        DestinationY = y2;
        ToolTip = tooltip;
    }   
}

BaseViewModel通过Fody Weaver实现属性更改事件。

问题

节点和链接按预期创建,但链接行的位置不正确。链接线应该从node1位置开始,到node2位置结束。

尝试但失败

我尝试将Style TargetType设置为Canvas,Grid和其他目标,但都没有效果。在DataTemplate中为网格创建样式也无济于事。

结束

请帮我解决这个问题,最重要的是要更好地理解我做错了什么。如果您需要任何其他信息,请与我们联系。

谢谢!

0 个答案:

没有答案