c# - 将 LineGeometry 与 EllipseGeometry 组合(在代码中,而不是 XAML)

标签 c# wpf geometry shapes

我正在尝试使用 WPF 创建自定义形状。对于初学者,我只是想创建一条简单的线,两端各有一个圆圈(我知道有 LineCaps,但这不是我要找的)。

我研究了一些教程,最简单的方法似乎是使用 CombinedGeometry。但是我无法让它正常工作。这是我创建几何对象的代码:

protected override Geometry DefiningGeometry
    {
        get
        {
            Point ellipseCenter1 = new Point(X1 - this.CapDiameter / 2, Y1 - this.CapDiameter / 2);
            Point ellipseCenter2 = new Point(X2 - this.CapDiameter / 2, Y2 - this.CapDiameter / 2);
            var ellipse1 = new EllipseGeometry(ellipseCenter1, CapDiameter, CapDiameter);
            var ellipse2 = new EllipseGeometry(ellipseCenter2, CapDiameter, CapDiameter);
            var line = new LineGeometry(this.StartPoint, this.EndPoint);

            var combined1 = new CombinedGeometry(GeometryCombineMode.Union, ellipse1, line);
            var combined2 = new CombinedGeometry(GeometryCombineMode.Union, combined1, ellipse2);

            // Freeze the geometry for performance benefits
            combined2.Freeze();

            return combined2;
        }
    }

但是,出于某种原因,这并没有划清界线。它绘制两个圆圈,但不绘制直线。显然我在这里遗漏了一些东西,有人可以指出什么吗? :)

以防万一,下面是类(class)的其余部分:

#region Dependency Properties
public static readonly DependencyProperty X1Property = 
    DependencyProperty.Register(
        "X1", 
        typeof(double),
        typeof(CappedLine), 
        new FrameworkPropertyMetadata(
                0.0, 
                FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure
            )
    );
public static readonly DependencyProperty Y1Property =
    DependencyProperty.Register(
        "Y1",
        typeof(double),
        typeof(CappedLine),
        new FrameworkPropertyMetadata(
                0.0,
                FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure
            )
    );
public static readonly DependencyProperty X2Property =
    DependencyProperty.Register(
        "X2",
        typeof(double),
        typeof(CappedLine),
        new FrameworkPropertyMetadata(
                0.0,
                FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure
            )
    );
public static readonly DependencyProperty Y2Property =
    DependencyProperty.Register(
        "Y2",
        typeof(double),
        typeof(CappedLine),
        new FrameworkPropertyMetadata(
                0.0,
                FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure
            )
    );
public static readonly DependencyProperty CapDiameterProperty =
    DependencyProperty.Register(
        "CapDiameter",
        typeof(double),
        typeof(CappedLine),
        new FrameworkPropertyMetadata(
                0.0,
                FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure
            )
    );

#endregion
#region CLR Properties

public double X1
{
    get { return (double)base.GetValue(X1Property); }
    set { base.SetValue(X1Property, value); }
}

public double Y1
{
    get { return (double)base.GetValue(Y1Property); }
    set { base.SetValue(Y1Property, value); }
}

public double X2
{
    get { return (double)base.GetValue(X2Property); }
    set { base.SetValue(X2Property, value); }
}

public double Y2
{
    get { return (double)base.GetValue(Y2Property); }
    set { base.SetValue(Y2Property, value); }
}

public Point StartPoint
{
    get { return (new Point(X1, Y1)); }
}

public Point EndPoint
{
    get { return (new Point(X2, Y2)); }
}

public double CapDiameter
{
    get { return (double)base.GetValue(CapDiameterProperty); }
    set { base.SetValue(CapDiameterProperty, value); }
}

#endregion

下面是我用来测试它的 XAML 代码:

<Window x:Class="HG.WPF.Shapes.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:shapes="clr-namespace:Tomers.WPF.Shapes"

    Title="WPF Custom Shapes" Height="300" Width="300" ResizeMode="NoResize">

    <Canvas Background="Black">
        <shapes:CappedLine X1="30" Y1="30" X2="200" Y2="200" CapDiameter="5" Fill="White" Stroke="White" StrokeThickness="2"></shapes:CappedLine>        
    </Canvas>

</Window>

最佳答案

如果您尝试Union,您的LineGeometry 对象将消失。来自 MSDN:

The GeometryCombineMode property specifies how the two geometries will be combined. Note that CombinedGeometry combines the area specified by two geometries, so geometries that do not have area (such as LineGeometry) disappear when combined.

您可以使用GeometryGroup:

GeometryGroup combined = new GeometryGroup();
combined.Children.Add(ellipse1);
combined.Children.Add(ellipse2);
combined.Children.Add(line);

或者您可以先在椭圆对象上使用 CombinedGeometry,然后使用 GeometryGroup 将其与直线组合在一起。

关于c# - 将 LineGeometry 与 EllipseGeometry 组合(在代码中,而不是 XAML),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16417950/

相关文章:

c# - ContextStaticAttribute 到底是什么?

C# 和 SQLGeometry : Combining Database Rows and WPF

c - 如何用 Cairo 创建同心三角形?

c++ - 将外部支撑物生成网格以进行3D打印

libgdx - 圆形纹理 libGdx

c# - asp.net mvc验证问题

c# - 如何查看传递给 EF Core 查询的参数?

c# - 读取已打印到控制台的值

wpf - HierarchicalDataTemplate.ItemTemplate 中的水平拉伸(stretch) WPF ContextMenu MenuItem

c# - 在自定义文本框中检测 PropertyChanged