我实现了一个扩展Canvas
的类,并使用MeasureOverride
的覆盖根据其上子对象的排列来更新大小。
目标是在Canvas
上放置可拖动的对象,这些对象可以拖到可见区域之外,并相应地进行ScrollViewer
更新。
我的类重写OnMouseMove
来将元素直接置于光标下方的其他元素的顶部-而不是设置Z索引,而是通过将元素从Children
的{我已经扩展了Canvas
,然后重新添加了元素。
将元素拖出可视区域时,滚动条会正确显示-我相信对象的删除和重新添加会触发大小更新,因为在这种情况下将调用MeasureOverride
我不希望OnMouseMove
方法将元素移到顶部,但是我仍然希望在将元素拖出可视区域时显示滚动条。
如何在不更改Children
的{{1}}内容的情况下重新计算画布的大小?
通过检测单击来进行拖动,将起点和对象直接存储在光标下方,如果在移动鼠标时拖动的元素不为null,则更新位置-拖动工作正常,但是我可以添加相关样本代码。
以下代码被混淆:
我的扩展Canvas
-
Canvas
我的public class MyCanvas : Canvas {
protected override void OnMouseMove(MouseEventArgs e) {
UIElement isOver = (UIElement)Mouse.DirectlyOver;
BringToTop(isOver);
}
private void BringToTop(UIElement element) {
this.Children.Remove(element);
this.Children.Add(element);
}
public void AddRect(int x, int y, int width, int height) {
Rect r = new Rect();
r.Width = width;
r.Height = height;
Canvas.SetTop(r, x);
Canvas.SetLeft(r, y);
Children.Add(r);
}
protected override Size MeasureOverride(Size constraint) {
if (InternalChildren.Count == 0) {
return new Size(0,0);
}
base.MeasureOverride(constraint);
double width = InternalChildren
.OfType<UIElement>()
.Max(i => i.DesiredSize.Width + (double)i.GetValue(LeftProperty));
double height = InternalChildren
.OfType<UIElement>()
.Max(i => i.DesiredSize.Height + (double)i.GetValue(TopProperty));
return new Size(width,height);
}
}
在MainWindow.xaml
中创建一个ScrollViewer
,如下所示-
DockPanel
我的<DockPanel LastChildFill="True" >
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
Name="scrollViewer">
</ScrollViewer>
</DockPanel>
添加了我的MainWindow.xaml.cs
并插入了一些MyCanvas
,如下所示-
Rect
答案 0 :(得分:0)
万一有人遇到类似问题,解决方法是在鼠标悬停方法上调用InvalidateMeasure()
,如下所示:
protected override void OnMouseMove(MouseEventArgs e) {
//In this case, the class extends Canvas, so InvalidateMeasure can be
//called directly.
InvalidateMeasure();
//If using a named Canvas object (i.e. myCanvasObject), InvalidateMeasure
//should be called on that object, not on the child objects
myCanvasObject.InvalidateMeasure();
}