c# - WPF/C# : Connect shapes dynamically with lines

标签 c# .net wpf canvas

我有以下 XAML 代码:

    <Grid>
    <ItemsControl ItemsSource="{Binding Items}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas></Canvas>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Ellipse Width="{Binding Radius}" Height="{Binding Radius}" Fill="{Binding BackColor}" />
                    <Line Stroke="Black" StrokeThickness="1" x:Name="_Line"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Left" Value="{Binding X}"/>
                <Setter Property="Canvas.Top" Value="{Binding Y}"/>
                <Setter Property="Line.X1" Value="{Binding LineX1}"/>
                <Setter Property="Line.X2" Value="{Binding LineX2}"/>
                <Setter Property="Line.Y1" Value="{Binding LineY1}"/>
                <Setter Property="Line.Y2" Value="{Binding LineY2}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>
</Grid>

它是一个 ItemsControl,其 ItemPanel 是一个 Canvas,用于动态放置我绑定(bind)到的 Obervable Collection 中的省略号。椭圆与 Canvas.Top 和 Canvas.Left 值的放置效果很好。但它不会绘制连接椭圆的线。

在后面的代码中,线条的位置计算正确,我检查过。

最佳答案

Line 属性不应应用于项目容器。相反,它们应该直接在 DataTemplate 中的 Line 控件上设置:

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <Grid>
            <Ellipse Width="{Binding Radius}" Height="{Binding Radius}"
                     Fill="{Binding BackColor}" />
            <Line Stroke="Black" StrokeThickness="1" x:Name="_Line"
                  X1="{Binding LineX1}" Y1="{Binding LineY1}"
                  X2="{Binding LineX2}" Y1="{Binding LineY2}"/>
        </Grid>
    </DataTemplate>
</ItemsControl.ItemTemplate>

请注意,LineX 和 LineY 属性值是相对于项目位置的。


编辑:所有元素绝对放置的替代解决方案是不在项目容器上设置 Canvas.Left 和 Canvas.Top 属性(即根本没有 ItemContainerStyle)。

您可以使用带有 EllipseGeometry 的 Path 而不是 Ellipse,并将 EllipseGeometry 的 Center 属性绑定(bind)到 Point 类型的 View 模型属性,作为 X 和 Y 的替代:

<ItemsControl ItemsSource="{Binding Items}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Canvas>
                <Path Fill="{Binding Fill}" Panel.ZIndex="1">
                    <Path.Data>
                        <EllipseGeometry Center="{Binding Center}"
                                         RadiusX="{Binding Radius}"
                                         RadiusY="{Binding Radius}"/>
                    </Path.Data>
                </Path>
                <Line Stroke="Black"
                      X1="{Binding LineX1}" Y1="{Binding LineY1}"
                      X2="{Binding LineX2}" Y2="{Binding LineY2}"/>
            </Canvas>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

关于c# - WPF/C# : Connect shapes dynamically with lines,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31310022/

相关文章:

c# - Webclient.DownloadString 崩溃

c# - 即使有可用数据,仍要从端口读取信息

c# - 允许多内容自定义控件中的命名元素

c# - 无法将 lambda 表达式转换为类型 'System.Delegate' 因为它不是委托(delegate)类型?

c# - .NET 列表排序在所有返回 0 后返回不同的顺序

c# - iTextSharp 签署在 MemoryStream 中创建的 PDF

C#:ToArray 性能

c# - 在构造函数中引用 "this"可以吗?

c# - 在 .NET 中获取内存配置文件数据

c# - 何时使用 BlockingCollection 以及何时使用 ConcurrentBag 而不是 List<T>?