Wpf 在已填充的画布中绘制新线

Wpf 在已填充的画布中绘制新线,wpf,wpf-controls,Wpf,Wpf Controls,所以我在我的网格上画了一幅画布,作为它的背景,它从资源字典中得到了一个画笔。这不是一个问题,它工作得很完美 但是现在我需要在它上面画一个开放的多边形,它的坐标是X和Y的数组…。所以点1是intX[0]和intY[0],依此类推 然后,根据一些计算,我会得到更多的属性,我需要添加一些水平线和垂直线“不再有多边形”。 在那之后,我需要把结果写在上面…所以在点x1,y1,我需要写结果 附言:这可能吗…。canvas是一个不错的选择吗?我选择canvas是因为坐标应该是绝对的,并且在调整窗口或对象的大小

所以我在我的网格上画了一幅画布,作为它的背景,它从资源字典中得到了一个画笔。这不是一个问题,它工作得很完美

但是现在我需要在它上面画一个开放的多边形,它的坐标是X和Y的数组…。所以点1是intX[0]和intY[0],依此类推

然后,根据一些计算,我会得到更多的属性,我需要添加一些水平线和垂直线“不再有多边形”。 在那之后,我需要把结果写在上面…所以在点x1,y1,我需要写结果

附言:这可能吗…。canvas是一个不错的选择吗?我选择canvas是因为坐标应该是绝对的,并且在调整窗口或对象的大小时不会改变。新绘制的线不应该删除以前绘制的线或背景
对不起,我的英语不好,我希望你能给我一些开始的指导

我不确定是否完全理解您的需要,但您可以使用自定义ItemsControl

首先,您需要一个实体来存储单个数据点的所有信息、位置和标签:

public class DataPoint : INotifyPropertyChanged
{
    private double left;
    public double Left
    {
        get { return left; }
        set
        {
            if (value != left)
            {
                left = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Left"));
            }
        }
    }

    private double top;
    public double Top
    {
        get { return top; }
        set
        {
            if (value != top)
            {
                top = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Top"));
            }
        }
    }

    private string text;
    public string Text
    {
        get { return text; }
        set
        {
            if (value != text)
            {
                text = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Text"));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
然后在您的VM中或直接在您的代码中,您可以使用ObservableCollection公开它:

希望这有帮助

public ObservableCollection<DataPoint> Points { get; set; }
<DockPanel>
    <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" HorizontalAlignment="Center">
        <Button Click="GetData_Click">Get Data</Button>
        <Button Click="GetText_Click">Get Text</Button>
    </StackPanel>
    <ItemsControl ItemsSource="{Binding Points}">
        <ItemsControl.Template>
            <ControlTemplate>
                <Canvas IsItemsHost="True" Background="AliceBlue" Width="500" Height="500"></Canvas>
            </ControlTemplate>
        </ItemsControl.Template>
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type local:DataPoint}">
                <Canvas>
                    <Ellipse Fill="Red" Width="6" Height="6" Canvas.Left="-3" Canvas.Top="-3"></Ellipse>
                    <TextBlock Text="{Binding Text}" Canvas.Left="10" Canvas.Top="0"></TextBlock>
                </Canvas>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="Canvas.Left" Value="{Binding Left}"/>
                <Setter Property="Canvas.Top" Value="{Binding Top}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>
</DockPanel>
Random rand = new Random();

private void GetData_Click(object sender, RoutedEventArgs e)
{
    const int max = 500;

    Points.Add(new DataPoint { Left = rand.Next(max), Top = rand.Next(max) });
    Points.Add(new DataPoint { Left = rand.Next(max), Top = rand.Next(max) });
    Points.Add(new DataPoint { Left = rand.Next(max), Top = rand.Next(max) });
    Points.Add(new DataPoint { Left = rand.Next(max), Top = rand.Next(max) });
}

private void GetText_Click(object sender, RoutedEventArgs e)
{
    foreach (DataPoint p in Points)
    {
        p.Text = ((char)('a' + rand.Next(26))).ToString();
    }
}