`System.Windows.Point` struct替换为class

时间:2013-07-18 01:50:27

标签: c# object .net-3.5

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

背景

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

我的代码与此相同:

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 struct。通过“表现得像”我的意思是,我希望能够像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.

这可能吗?

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

2 个答案:

答案 0 :(得分:1)

实施implicit conversion运营商:

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

这意味着无论您何时尝试使用需要CPoint的{​​{1}}(反之亦然),编译器都会插入对这些转换运算符的调用。因此,您的使用将完全符合您的要求:

Point

但是,根据您的代码评论AFAIK,如果您随后更改Rect r = new Rect(cp1, cp2); 以使其自动传播到Rect,则无法在创建cp1.X = 9000后进行此操作。特别是Rect本身就是一个结构。我认为你必须完全考虑不同的设计/用法,如果那是你想要达到的目的。

编辑:根据您的要求,可能需要考虑的设计可能是这样的。首先,定义您的Rect在其属性发生变化时通知:

CPoint

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

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

请注意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,X2 X1 Y1 , Y2`属性相关联。

据推测,你也可以将这些点用于其他形状,这样它们就不会被绑定到任何一种形状类型。

,

有一些重复,分配事件为行分配初始值,但我确信如果有必要,可以进行一些调整。

答案 1 :(得分:0)

不,你不能通过改变其构成点来移动矩形。那是设计上的。 但是,WPF 允许您通过数据绑定和依赖项属性执行您想要执行的操作。

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

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

有关WPF数据绑定的更多信息,请查看here.