如果您愿意,我可以编写这个代码,但是以下是我的做法...
维护一个 pair< x_position, height > 的列表,并按 X 排序。在自定义控件中完成此操作。
使用 for 循环绘制它。通过查找列表来确定点击事件。处理一些鼠标拖动事件,更新屏幕。
for 循环将查看 mylist[i] 和 mylist[i+1]。使用该信息绘制矩形。
我通常不使用 WPF 进行编码,但如果您愿意,我可以在半小时内弄清楚它。
以下是一些代码............. 将代码添加到命名空间,构建,然后将组件添加到表单中:
public class Pair
{
public Pair()
{
}
public Pair(float first, float second)
{
this.First = first;
this.Second = second;
}
public float First { get; set; }
public float Second { get; set; }
};
public class ImageButton : FrameworkElement
{
List<Pair> items;
Boolean dragDown = false;
bool dragVert = false;
int dragSeg = -1;
public ImageButton() {
items = new List<Pair>();
items.Add(new Pair(0, 0));
items.Add(new Pair(40, 40));
items.Add(new Pair(60, 0));
items.Add(new Pair(100, 20));
items.Add(new Pair(115, 0));
items.Add(new Pair(185, 20));
items.Add(new Pair(215, 0));
items.Add(new Pair(300, 0));
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
int seg;
bool vert;
if (getSegment(e.GetPosition(this).X, e.GetPosition(this).Y, out seg, out vert))
{
dragDown = true;
dragSeg = seg;
dragVert = vert;
}
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseButtonEventArgs e)
{
dragDown = false;
base.OnMouseUp(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
double basey = RenderSize.Height - 10;
int seg;
bool vert;
if (!dragDown)
{
if (getSegment(e.GetPosition(this).X, e.GetPosition(this).Y, out seg, out vert))
{
if (vert)
{
Cursor = Cursors.SizeWE;
}
else
{
Cursor = Cursors.SizeNS;
};
}
else
{
Cursor = Cursors.No;
}
}
else
{
if (dragVert)
{
items[dragSeg].First = (int) e.GetPosition(this).X;
InvalidateVisual();
}
else
{
items[dragSeg].Second = (int)(basey - ((int)e.GetPosition(this).Y));
InvalidateVisual();
}
}
base.OnMouseMove(e);
}
protected override void OnRender(DrawingContext dc)
{
Brush b = new SolidColorBrush(Color.FromRgb(40,40,40));
dc.DrawRectangle(b, new Pen(b, 2), new Rect(0, 0, this.RenderSize.Width, RenderSize.Height));
Pen p = new Pen(new SolidColorBrush(Color.FromRgb(240, 240, 240)), 2);
double basey = RenderSize.Height - 10;
for (int i = 0; i < items.Count-1; i++)
{
Brush br = new SolidColorBrush(Color.FromRgb(240, 40, 40));
Rect t = new Rect(items[i].First,basey-items[i].Second, items[i+1].First-items[i].First,items[i].Second);
dc.DrawRectangle(br, p, t);
}
}
bool getSegment(double x, double y, out int index, out bool vert)
{
double basey = RenderSize.Height - 10;
index = 0;
vert = false;
for (int i = 0; i < items.Count - 1; i++)
{
if ((x >= (items[i].First - 3)) && ( x <= (items[i].First + 3))) {
if ((y < (basey)) && (y>=(basey-items[i].Second))) {
index = i;
vert = true;
return true;
}
}
if ((x >= (items[i + 1].First - 3)) && (x <= (items[i + 1].First + 3)))
{
if ((y < (basey)) && (y >= (basey - items[i].Second)))
{
index = i+1;
vert = true;
return true;
}
}
if ((x >= (items[i].First) && (x <= (items[i+1].First)))) {
if ((y < (basey - items[i].Second + 3)) && (y > (basey - items[i].Second - 3)))
{
index = i;
vert = false;
return true;
}
}
}
return false;
}
}
当拖动片段时,请勿重叠它们 - 我没有为此编码。但这允许查看信号并移动信号。
![Sample of provided component](https://istack.dev59.com/0V0Fv.webp)
通过鼠标调整大小后:
![enter image description here](https://istack.dev59.com/ptqKq.webp)
PS:我没有尝试优化或制作任何生产代码,只是为了您而匆忙完成。