在已填充的画布中绘制新行

时间:2014-08-14 18:37:29

标签: wpf wpf-controls

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

但现在我需要在其上绘制一个开放式多边形,它将其坐标作为X和Y的数组。让我们说intX [i]和intY [i]数组....所以第1点是intX [0]和intY [0],依此类推......

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

Ps:这甚至可能......画布是一个很好的选择'我选择了画布,因为坐标应该是绝对的,并且当窗口或对象调整大小时不会改变'新绘制的线不应该删除先前绘制的线或背景' 抱歉,或者我的英语不好,我希望你能引导我开始......

1 个答案:

答案 0 :(得分:0)

我不确定是否完全了解您的需求,但您可以使用自定义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>

localDataPoint类名称空间的映射。

以下是用于演示目的的两个事件处理程序:

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();
    }
}

希望这有帮助。