将LineGeometry与EllipseGeometry结合使用(在代码中,不是XAML) [英] Combining LineGeometry with EllipseGeometry (in code, not XAML)

查看:130
本文介绍了将LineGeometry与EllipseGeometry结合使用(在代码中,不是XAML)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用WPF创建一个自定义形状。对于初学者,我只是试图创建一个简单的线,每一端都有一个圆圈(我知道有LineCaps,但这不是我要找的)。



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

 受保护的覆盖几何定义几何
{
get
{
点椭圆中心1 =新点(X1 - this.CapDiameter / 2,Y1 - this.CapDiameter / 2);
Point ellipseCenter2 =新点(X2 - this.CapDiameter / 2,Y2 - this.CapDiameter / 2);
var ellipse1 =新的椭圆几何(ellipseCenter1,CapDiameter,CapDiameter);
var ellipse2 =新的椭圆几何(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);

//冻结几何以获得性能优势
combined2.Freeze();

回报合并2;






$ b但是,由于某些原因,该线。它绘制两个圆圈,但不是线条。很明显,我在这里错过了一些东西,有人能指出什么吗? :)



为了防万一,这里是其余的课程:

  #region依赖属性
public static readonly DependencyProperty X1Property =
DependencyProperty.Register(
X1,
typeof(double),
typeof CappedLine),
新的FrameworkPropertyMetadata(
0.0,
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure

);
public static readonly DependencyProperty Y1Property =
DependencyProperty.Register(
Y1,
typeof(double),
typeof(CappedLine),
新的FrameworkPropertyMetadata (
0.0,
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure

);
public static readonly DependencyProperty X2Property =
DependencyProperty.Register(
X2,
typeof(double),
typeof(CappedLine),
新的FrameworkPropertyMetadata (
0.0,
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure

);
public static readonly DependencyProperty Y2Property =
DependencyProperty.Register(
Y2,
typeof(double),
typeof(CappedLine),
新的FrameworkPropertyMetadata (
0.0,
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure

);
public static readonly DependencyProperty CapDiameterProperty =
DependencyProperty.Register(
CapDiameter,
typeof(double),
typeof(CappedLine),
新的FrameworkPropertyMetadata (
0.0,
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure

);
$ b $ #endregion
#region CLR属性

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 ShapesHeight = 300Width =300ResizeMode =NoResize>

<画布背景=黑色>
<形状:CappedLine X1 =30Y1 =30X2 =200Y2 =200CapDiameter =5Fill =WhiteStroke =WhiteStrokeThickness =2> ;< /形状:CappedLine>
< / Canvas>

< / Window>


解决方案

您的 LineGeometry Union 它们,c $ c>对象将会消失。来自MSDN:


GeometryCombineMode属性指定两个几何图形将如何组合。请注意,CombinedGeometry将由
两个几何图形指定的区域组合在一起,因此没有面积的几何图形(例如
LineGeometry)在合并时消失。

您可以使用 GeometryGroup

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

或者您可以在椭圆上使用 CombinedGeometry 首先,然后使用 GeometryGroup 将它们与行一起分组。

I'm trying to create a custom shape with WPF. For starters I was just trying to create a simple line, that has a circle at each end (I know there are LineCaps, but that's not what I'm looking for).

I've looked into some tutorials and the easiest way to do that, seems to use a CombinedGeometry. However I can't get it to work properly. Here is my code that creates the geometry object:

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

However, for some reason, this doesn't draw the line. It draws both circles, but not the line. Obviously I'm missing something here, could someone point out what? :)

Just in case it matters, here is the rest of the 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

And here is the XAML code I used to test it:

<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>

解决方案

Your LineGeometry objects will vanish if you try to Union them. From 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.

You can use GeometryGroup:

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

or you can use CombinedGeometry on the ellipse objects first, and then group that together with the line using GeometryGroup.

这篇关于将LineGeometry与EllipseGeometry结合使用(在代码中,不是XAML)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆