我需要类似于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.
这可能吗?
我需要一些存取器吗?我知道如何创建返回一些属性的访问器,但我不知道如何编写返回整个类的访问器。
答案 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.