`System.Windows.Point`用类替换结构
本文关键字:替换 结构 Point System Windows | 更新日期: 2023-09-27 18:23:36
我需要类似于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.
这可能吗
我需要一些访问者吗?我知道如何生成返回某些属性的访问器,但不知道如何编写返回整个类的访问器。
实现隐式转换运算符:
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);
}
}
这意味着,无论您在哪里尝试使用需要Point
的CPoint
(反之亦然),编译器都会插入对这些转换运算符的调用。因此,您的使用将完全符合您的要求:
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
分配事件和将初始值分配给行有点重复,但我相信如果必要的话,进行一些调整会消除这种情况。
否,不能通过改变矩形的组成点来移动矩形。这是故意的。WPF确实允许您通过数据绑定和依赖属性来做您想做的事情。
特别是对于矩形,您希望绑定到RadiusX和RadiusY属性,因为它们是矩形提供的可绑定依赖属性。
将Rectangle绑定到模型对象时,请确保模型对象实现INotifyPropertyChanged或提供自己的依赖属性。
有关WPF数据绑定的更多信息,请查看此处。