【问题标题】:Why are my polygons being drawn in the wrong location?为什么我的多边形被绘制在错误的位置?
【发布时间】:2018-10-17 06:14:48
【问题描述】:

我正在为一项作业练习 C# 基本 WPF/XAML 绘图,但我一开始就无法弄清楚为什么我的多边形被绘制在错误的位置。

我的窗口是 1280x720 固定的,不可调整大小。我正在尝试通过以下方式以编程方式创建我的多边形:

  1. 在我想要的坐标中创建点: `

    • [0,0]
    • [最大高度,0],
    • [最大高度,最大宽度],
    • [0, 最大宽度],
    • [最大高度/2,最大宽度/2]

`

  1. 创建由三个点、[0,0] 和两条边组成的多边形。我的屏幕应该分成四个三角形。

我尝试将代码分解为非常明确的内容,以查看是否可以找出问题所在,所以这就是我所拥有的:

private void CreatePolygons()
{ 
    List<Point> PointList = new List<Point>
    {
        new Point(MainUI.Height / 2, MainUI.Width / 2),
        new Point(0, 0),
        new Point(0, MainUI.Height),
        new Point(MainUI.Width, MainUI.Height),
        new Point(MainUI.Width, 0)                
    };

    Polygon p1 = new Polygon();
    Polygon p2 = new Polygon();
    Polygon p3 = new Polygon();
    Polygon p4 = new Polygon();

    p1.Points.Add(PointList[0]);
    p1.Points.Add(PointList[1]);
    p1.Points.Add(PointList[2]);

    p2.Points.Add(PointList[0]);
    p2.Points.Add(PointList[2]);
    p2.Points.Add(PointList[3]);

    p3.Points.Add(PointList[0]);
    p3.Points.Add(PointList[3]);
    p3.Points.Add(PointList[4]);

    p4.Points.Add(PointList[0]);
    p4.Points.Add(PointList[4]);
    p4.Points.Add(PointList[1]);

    p1.Stroke = System.Windows.Media.Brushes.LightSkyBlue;
    p2.Stroke = System.Windows.Media.Brushes.LightSkyBlue;
    p3.Stroke = System.Windows.Media.Brushes.LightSkyBlue;
    p4.Stroke = System.Windows.Media.Brushes.LightSkyBlue;

    p1.StrokeThickness = 1;
    p2.StrokeThickness = 1;
    p3.StrokeThickness = 1;
    p4.StrokeThickness = 1;

    MainGrid.Children.Add(p1);
    MainGrid.Children.Add(p2);
    MainGrid.Children.Add(p3);
    MainGrid.Children.Add(p4);
}

最终结果是一个完全错位的网格,我无法理解它最终创建的坐标指的是什么:

我错过了什么?

【问题讨论】:

    标签: c# wpf xaml polygon


    【解决方案1】:

    您在第一点不小心交换了WidthHeight

    new Point(MainUI.Height / 2, MainUI.Width / 2),
    

    应该是:

    new Point(MainUI.Width / 2, MainUI.Height / 2),
    

    进一步,假设MainUI 是应用程序窗口本身,点仍然会有点偏离,因为窗口的Height包括其标题栏高度。你最好使用MainGrid.ActualWidthMainGrid.ActualHeight

    List<Point> PointList = new List<Point>
    {
        new Point(MainGrid.ActualWidth / 2, MainGrid.ActualHeight / 2),
        new Point(0, 0),
        new Point(0, MainGrid.ActualHeight),
        new Point(MainGrid.ActualWidth, MainGrid.ActualHeight),
        new Point(MainGrid.ActualWidth, 0)
    };
    

    【讨论】:

    • 使用ActualWidthActualHeight 而不是简单的HeightWidth 会导致它不绘制任何内容。我认为这是因为我的网格没有定义大小,所以我用我的 Window 对象代替,它也没有绘制任何东西。有原因吗?在我之前得到的评论之后,使用 Canvas 有什么好处?
    • 实际上原因是它被调用得太早 - 在布局过程发生之前。尝试将Loaded 事件处理程序附加到您的窗口并在内部调用CreatePolygons 方法(或SizeChanged,如果您想在窗口大小更改时将点保留在正确的位置,但您需要在之前删除之前的点创建新的)
    【解决方案2】:

    作为所有多边形点计算的替代方案,您可以使用这个简单的路径元素,它会产生相同的输出并自动拉伸:

    <Grid>
        <Path Stretch="Fill" Stroke="LightSkyBlue" StrokeThickness="1"
              Data="M0,0 L1,0 1,1 0,1Z M0,0 L1,1 M0,1 L1,0"/>
    </Grid>
    

    【讨论】:

    • 我需要它们成为单独的元素,因为它们将与另一个组件交互。我相信我不能用 Path 元素做到这一点,因为它将是一个单一的实体
    • 您可能有多个路径仍然可以从它们在数据中拉伸几何图形的能力中受益。
    【解决方案3】:

    除了你混淆了第一点的宽度和高度之外,我建议不要在后面的代码中创建像多边形这样的 UI 元素。最好像这样使用 ItemsControl:

    <Grid SizeChanged="MainUISizeChanged">
        <ItemsControl x:Name="polygons">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Polygon Stroke="LightSkyBlue" StrokeThickness="1"
                             Points="{Binding}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
    

    并将其 ItemsSource 属性分配给 PointCollections 的集合,例如每当您的 MainUI 元素的大小发生变化时:

    private void MainUISizeChanged(object sender, SizeChangedEventArgs e)
    {
        var points = new List<Point>
        {
            new Point(e.NewSize.Width / 2, e.NewSize.Height / 2),
            new Point(0, 0),
            new Point(0, e.NewSize.Height),
            new Point(e.NewSize.Width, e.NewSize.Height),
            new Point(e.NewSize.Width, 0)
        };
    
        polygons.ItemsSource = new List<PointCollection>
        {
            new PointCollection(new Point[] { points[0], points[1], points[2] }),
            new PointCollection(new Point[] { points[0], points[2], points[3] }),
            new PointCollection(new Point[] { points[0], points[3], points[4] }),
            new PointCollection(new Point[] { points[0], points[4], points[1] }),
        };
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-02
      相关资源
      最近更新 更多