首先,我需要画一条垂直线和一条水平线。我使用GeometryGroup来实现这一点。它看起来像这样
自定义类代码:
public class QuadrantGate1 : Shape
{
#region Constructors
/// <summary>
/// Instantiate a new instance of a line.
/// </summary>
public QuadrantGate1()
{
}
#endregion
#region Dynamic Properties
public double VerticalY1
{
get { return (double)GetValue(VerticalY1Property); }
set { SetValue(VerticalY1Property, value); }
}
// Using a DependencyProperty as the backing store for VerticalY1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty VerticalY1Property =
DependencyProperty.Register("VerticalY1", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double VerticalY2
{
get { return (double)GetValue(VerticalY2Property); }
set { SetValue(VerticalY2Property, value); }
}
// Using a DependencyProperty as the backing store for VerticalY2. This enables animation, styling, binding, etc...
public static readonly DependencyProperty VerticalY2Property =
DependencyProperty.Register("VerticalY2", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(256.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double VerticalX
{
get { return (double)GetValue(VerticalXProperty); }
set { SetValue(VerticalXProperty, value); }
}
// Using a DependencyProperty as the backing store for VerticalX1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty VerticalXProperty =
DependencyProperty.Register("VerticalX", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(128.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double HorizontalX1
{
get { return (double)GetValue(HorizontalX1Property); }
set { SetValue(HorizontalX1Property, value); }
}
// Using a DependencyProperty as the backing store for HorizontalX1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HorizontalX1Property =
DependencyProperty.Register("HorizontalX1", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double HorizontalX2
{
get { return (double)GetValue(HorizontalX2Property); }
set { SetValue(HorizontalX2Property, value); }
}
// Using a DependencyProperty as the backing store for HorizontalX2. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HorizontalX2Property =
DependencyProperty.Register("HorizontalX2", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(256.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double HorizontalY
{
get { return (double)GetValue(HorizontalYProperty); }
set { SetValue(HorizontalYProperty, value); }
}
// Using a DependencyProperty as the backing store for HorizontalY. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HorizontalYProperty =
DependencyProperty.Register("HorizontalY", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(128.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
#endregion
#region Protected Methods and Properties
protected override Geometry DefiningGeometry
{
get
{
_geometryGroup = new GeometryGroup();
_geometryGroup.FillRule = FillRule.Nonzero;
DrawTwoLinesGeometry(_geometryGroup);
_path = new Path();
_path.Data = _geometryGroup;
return _geometryGroup;
}
}
private void DrawTwoLinesGeometry(GeometryGroup geometryGroup)
{
try
{
_lineGeometry1 = new LineGeometry()
{
StartPoint = new Point { X = HorizontalX1, Y = HorizontalY },
EndPoint = new Point { X = HorizontalX2, Y = HorizontalY }
};
_lineGeometry2 = new LineGeometry()
{
StartPoint = new Point { X = VerticalX, Y = VerticalY1 },
EndPoint = new Point { X = VerticalX, Y = VerticalY2 }
};
_geometryGroup.Children.Add(_lineGeometry1);
_geometryGroup.Children.Add(_lineGeometry2);
}
catch (Exception e)
{
}
}
#endregion
#region Private Methods and Members
private GeometryGroup _geometryGroup;
private LineGeometry _lineGeometry1;
private LineGeometry _lineGeometry2;
private Path _path;
#endregion
}
xaml代码:
第二,我需要移动两行。鼠标在水平线上时,可以上下移动水平线,垂直线保持静止。
当鼠标在垂直线上时,垂直线可以向左或向右移动,水平线保持静止。
当鼠标位于两条线的交叉点上时,两条线都可以移动,水平线可以上下移动,垂直线可以左右移动。
我想先移动两行,所以自定义类代码:
public class QuadrantGate1 : Shape
{
#region Constructors
/// <summary>
/// Instantiate a new instance of a line.
/// </summary>
public QuadrantGate1()
{
this.MouseDown += QuadrantGate_MouseDown;
this.MouseMove += QuadrantGate_MouseMove;
this.MouseLeftButtonUp += QuadrantGate_MouseLeftButtonUp;
}
#endregion
#region Dynamic Properties
public double VerticalY1
{
get { return (double)GetValue(VerticalY1Property); }
set { SetValue(VerticalY1Property, value); }
}
// Using a DependencyProperty as the backing store for VerticalY1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty VerticalY1Property =
DependencyProperty.Register("VerticalY1", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double VerticalY2
{
get { return (double)GetValue(VerticalY2Property); }
set { SetValue(VerticalY2Property, value); }
}
// Using a DependencyProperty as the backing store for VerticalY2. This enables animation, styling, binding, etc...
public static readonly DependencyProperty VerticalY2Property =
DependencyProperty.Register("VerticalY2", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(256.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double VerticalX
{
get { return (double)GetValue(VerticalXProperty); }
set { SetValue(VerticalXProperty, value); }
}
// Using a DependencyProperty as the backing store for VerticalX1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty VerticalXProperty =
DependencyProperty.Register("VerticalX", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(128.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double HorizontalX1
{
get { return (double)GetValue(HorizontalX1Property); }
set { SetValue(HorizontalX1Property, value); }
}
// Using a DependencyProperty as the backing store for HorizontalX1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HorizontalX1Property =
DependencyProperty.Register("HorizontalX1", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double HorizontalX2
{
get { return (double)GetValue(HorizontalX2Property); }
set { SetValue(HorizontalX2Property, value); }
}
// Using a DependencyProperty as the backing store for HorizontalX2. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HorizontalX2Property =
DependencyProperty.Register("HorizontalX2", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(256.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double HorizontalY
{
get { return (double)GetValue(HorizontalYProperty); }
set { SetValue(HorizontalYProperty, value); }
}
// Using a DependencyProperty as the backing store for HorizontalY. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HorizontalYProperty =
DependencyProperty.Register("HorizontalY", typeof(double), typeof(QuadrantGate1), new FrameworkPropertyMetadata(128.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
#endregion
#region Protected Methods and Properties
protected override Geometry DefiningGeometry
{
get
{
_geometryGroup = new GeometryGroup();
_geometryGroup.FillRule = FillRule.Nonzero;
DrawTwoLinesGeometry(_geometryGroup);
_path = new Path();
_path.Data = _geometryGroup;
return _geometryGroup;
}
}
private void DrawTwoLinesGeometry(GeometryGroup geometryGroup)
{
try
{
_lineGeometry1 = new LineGeometry()
{
StartPoint = new Point { X = HorizontalX1, Y = HorizontalY },
EndPoint = new Point { X = HorizontalX2, Y = HorizontalY }
};
_lineGeometry2 = new LineGeometry()
{
StartPoint = new Point { X = VerticalX, Y = VerticalY1 },
EndPoint = new Point { X = VerticalX, Y = VerticalY2 }
};
_geometryGroup.Children.Add(_lineGeometry1);
_geometryGroup.Children.Add(_lineGeometry2);
}
catch (Exception e)
{
}
}
#endregion
#region Events Methods
private void QuadrantGate_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.OriginalSource.GetType() == typeof(QuadrantGate1))
{
this.mouseBefore = e.GetPosition(this);
QuadrantGate1 quadrantGate = (QuadrantGate1)e.OriginalSource;
startBefore.X = VerticalX;
startBefore.Y = HorizontalY;
quadrantGate.CaptureMouse();
}
}
GeometryCollection GeometryGroupChildren(GeometryGroup geometryGroup)
{
GeometryCollection geometries = new GeometryCollection();
if (geometryGroup == null)
return null;
else
{
geometries = geometryGroup.Children;
return geometries;
}
}
private void QuadrantGate_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
if (e.OriginalSource != null && e.OriginalSource.GetType() == typeof(QuadrantGate1))
{
QuadrantGate1 quadrantGate = (QuadrantGate1)e.OriginalSource;
Point p = e.GetPosition(this);
VerticalX = startBefore.X + (p.X - mouseBefore.X);
HorizontalY = startBefore.Y + (p.Y - mouseBefore.Y);
}
}
}
private void QuadrantGate_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (e.OriginalSource.GetType() == typeof(QuadrantGate1))
{
QuadrantGate1 quadrantGate = (QuadrantGate1)e.OriginalSource;
quadrantGate.ReleaseMouseCapture();
}
}
#endregion
#region Private Methods and Members
private GeometryGroup _geometryGroup;
private LineGeometry _lineGeometry1;
private LineGeometry _lineGeometry2;
private Path _path;
Point mouseBefore;
Point startBefore;
#endregion
}
但是这两行并没有按照我的意愿移动。这两行的移动与鼠标不一致。
奇怪的是,如果注释掉这些行_geometryGroup.Children.Add(_lineGeometry1);
或此_geometryGroup.Children.Add(_lineGeometry2);
之一,则其余行可以成功移动。这是水平线:
,
和垂直线:
答案 0 :(得分:0)
通过实现代码,我看到了渲染问题,您还可以看到是否只是按下鼠标并最小化屏幕,再次打开它就可以看到行移到了另一个位置。
您可以尝试使用StreamGeometryContext代替GeometryGroup
,下面是代码DefiningGeometry get Property。
protected override Geometry DefiningGeometry
{
get
{
StreamGeometry geometry = new StreamGeometry();
geometry.FillRule = FillRule.EvenOdd;
using (StreamGeometryContext ctx = geometry.Open())
{
ctx.BeginFigure(new Point(HorizontalX1, HorizontalY), true /* is filled */, true /* is closed */);
ctx.LineTo(new Point(HorizontalX2, HorizontalY), true /* is stroked */, false /* is smooth join */);
ctx.BeginFigure(new Point(VerticalX, VerticalY1), true /* is filled */, true /* is closed */);
ctx.LineTo(new Point(VerticalX, VerticalY2), true /* is stroked */, false /* is smooth join */);
}
//geometry.Freeze();
_path = new Path();
_path.Data = geometry;
return geometry;
}
}