1

我需要类似于的类型System.Windows.Point,但我需要类,而不是结构。

背景

我尝试创建几个点并将它们放在列表中,并更改它们的坐标。

我的代码相当于这个:

List<Point> listofpoints = new List<Point>();

listofpoints.Add(new Point(1, 1));
listofpoints.Add(new Point(5, 5));

Line line = new Line();

line.Brush = new SolidColorBrush(Colors.Black);

line.X1 = listofpoints[0].X;
line.Y1 = listofpoints[0].X;
line.X2 = listofpoints[1].X;
line.Y2 = listofpoints[1].X;

canvas1.Children.Add(line);


// later I had to change these points coordinates
// I tried to move shapes with these points by changing only these point properties
listofpoints[0].X = 50;
listofpoints[0].Y = 50;

// but i cant, (probably) because struct is not reference type

我有的

我编写了简单的类,使我能够更改列表中的点,而无需用新点替换它们。

public class CPoint
{ 
    public double X;
    public double Y;
}

我想要的是?

我希望这个类表现得像System.Windows.Point结构。“表现得像”我的意思是,我希望能够CPoint像这样创建矩形:

CPoint cp1 = new CPoint();

cp1.X = 0;
cp1.Y = 0;

CPoint cp2 = new CPoint();

cp2.X = 10;
cp2.Y = 20;

Rect r = new Rect(cp1, cp2); // this is just example, in fact - I use other shapes

// i want to be able to move that rectangle by only changing cp1 and cp2 properties.

这可能吗?

我需要一些访问器吗?我知道如何制作返回某些属性的访问器,但我不知道如何编写返回整个类的访问器。

4

2 回答 2

1

实现隐式转换运算符:

public class CPoint
{ 
    public double X;
    public double Y;

    public static implicit operator Point(CPoint cpoint)
    {
        return new Point(cpoint.X, cpoint.Y);
    }

    public static implicit operator CPoint(Point point)
    {
        return new CPoint(point.X, point.Y);
    }
}

这意味着无论您在哪里尝试使用需要 a 的CPoint地方Point(反之亦然),编译器都会插入对这些转换运算符的调用。因此,您的使用将完全符合您的要求:

Rect r = new Rect(cp1, cp2);

但是,根据您的代码注释 AFAIK,一旦您创建 , 就不可能做到这一点Rect,如果您随后更改cp1.X = 9000为让它自动传播到它,Rect特别是因为Rect它本身是一个结构。我认为如果这是您想要实现的目标,您将不得不完全考虑不同的设计/用法。

编辑:根据您的要求,要考虑的可能设计可能是这样的。首先,定义您CPoint的属性更改时通知:

public class CPoint
{ 
    public event Action<CPoint, double> XChanged;
    public event Action<CPoint, double> YChanged;

    private double _X;
    public double X
    {
        get { return _X; }
        set
        {
            _X = value;

            var xchanged = XChanged;
            if (xchanged != null)
                xchanged(this, value);
        }
    }

    private double _Y;
    public double Y
    {
        get { return _Y; }
        set
        {
            _Y = value;

            var ychanged = YChanged;
            if (ychanged != null)
                ychanged(this, value);
        }
    }

    public CPoint()
    {

    }

    public CPoint(double x, double y)
    {
        this._X = x;
        this._Y = y;
    }
}

然后,因为我认为,您的意图是与多条线共享同一个点(例如绘制 N 边多边形),将线与点链接:

List<CPoint> listofpoints = new List<CPoint>();

listofpoints.Add(new CPoint(1, 1));
listofpoints.Add(new CPoint(5, 5));

Line line = new Line();

line.Brush = new SolidColorBrush(Colors.Black);

listofpoints[0].XChanged += (p, x) => line.X1 = x;
listofpoints[0].YChanged += (p, y) => line.Y1 = y;
listofpoints[1].XChanged += (p, x) => line.X2 = x;
listofpoints[1].YChanged += (p, y) => line.Y2 = y;

line.X1 = listofpoints[0].X;
line.Y1 = listofpoints[0].X;
line.X2 = listofpoints[1].X;
line.Y2 = listofpoints[1].X;

canvas1.Children.Add(line);

XChanged请注意和事件的侦听器YChanged以及它们如何与 Line 的X1, X2 ,Y1 ,Y2` 属性相关联。

大概您还会将这些点用于其他形状,这样它们就不会被绑定到任何一种形状类型。

listofpoints[0].X = 50; //propagates to line.X1 via the event
listofpoints[0].Y = 50; //propagates to line.Y1 via the event

在分配事件并将初始值分配给该行时存在一些重复,但我确信如果有必要进行一些调整将消除这种情况。

于 2013-07-18T01:55:47.713 回答
0

不,您不能通过改变其组成点来移动矩形。这是设计使然。不过, WPF确实允许您通过数据绑定和依赖属性来做您想做的事情。

特别是对于 Rectangle,您希望绑定到 RadiusX 和 RadiusY 属性,因为它们是 Rectangle 提供的可绑定依赖属性。

当您将 Rectangle 绑定到模型对象时,请确保您的模型对象实现INotifyPropertyChanged或提供其自己的依赖项属性。

有关 WPF 数据绑定的更多信息,请查看此处。

于 2013-07-18T02:15:30.700 回答