我需要在(矩形/区域/边界)中找到UIElement
s。
主窗口 我正在执行以下操作:
- 我将鼠标向下注册为起始位置。
- 我重新设置鼠标向上的位置。
- 现在我需要在开始之间的矩形中找到 ll(按钮、文本框等) 位置和结束位置。
我在 msdn 中找到了HitTest
的方法,但它只是为了一点。 我想,走过成立的所有点矩形 这是一个性能灾难。
http://msdn.microsoft.com/en-us/library/ms752097.aspx
我基于 MVVM 模式的代码:
private ObservableCollection<UIElementViewModel> wells;
private Point stratPoint; // Mouse down
public ICommand MouseUpRightCommand
{
get
{
if (this.mouseUpRightCommand == null)
{
this.mouseUpRightCommand = new RelayCommands(
param =>
{
if (param is MouseButtonEventArgs)
{
var e = (param as MouseButtonEventArgs);
//Set the end point
endPosition = e.GetPosition(((ItemsControl)e.Source));
// for example, here I want to find all controls(UIElements) in the
// founded rectangle of stratPoint and endPosition.
}
});
}
return this.mouseUpRightCommand;
}
}
还有其他想法或更好的方法吗?
谢谢
FrameworkElement
(扩展UIElement
)而不是UIElement
,以便使用ActualWidth
和ActualHeight
属性
然后创建一个静态类来执行一些数学MouseUtils
使用这些静态字段
private static double _dContainerTop;
private static double _dContainerBottom;
private static double _dContainerLeft;
private static double _dContainerRight;
private static double _dCursorTop;
private static double _dCursorLeft;
private static double _dCursorRight;
private static double _dCursorBottom;
和那些静态方法
private static void FindValues(FrameworkElement element, Visual rootVisual)
{
var containerTopLeft = container.TransformToAncestor(rootVisual).Transform(new Point(0, 0));
_dContainerTop = containerTopLeft.Y;
_dContainerBottom = _dContainerTop + container.ActualHeight;
_dContainerLeft = containerTopLeft.X;
_dContainerRight = _dContainerLeft + container.ActualWidth;
}
和
public static bool IsElementUnderRectCursor(FrameworkElement element, Point startPoint, Point endPoint, Visual rootVisual)
{
_dCursorTop=Math.Min(startPoint.Y, endPoint.Y);
_dCursorBottom=Math.Max(startPoint.Y, endPoint.Y);
_dCursorLeft=Math.Min(startPoint.X, endPoint.X);
_dCursorRight=Math.Max(startPoint.X, endPoint.X);
FindValues(container, rootVisual);
if (_dContainerTop < _dCursorTop|| _dCursorBottom< _dContainerBottom )
{
return false;
}
if (_dContainerLeft < _dCursorLeft|| _dContainerRight < _dCursorRight)
{
return false;
}
return true;
}
例如,Rootvisual
是你的窗口;
然后循环ObservableCollection<FrameworkElement> wells
并将该函数调用IsElementUnderRectCursor
。
这灵感来自:Kinecting the Dots
Astreal再次感谢您的回答。大功告成。我只是将选择代码从模型视图移动到视图。仅在 UI 中完成的选择。
private void SelectWells(RectangleGeometry selectionRectangle, FrameworkElement frameworkElement)
{
var items = GetItemsControl(frameworkElement);
foreach (var item in items.Items)
{
var viusalItem = (ContentPresenter)items.ItemContainerGenerator.ContainerFromItem(item);
var wellControl = this.GetWellControl(viusalItem);
var relativePoint = wellControl.TransformToAncestor(items).Transform(new Point(0, 0));
var controlRectangle =
new RectangleGeometry(
new Rect(relativePoint.X, relativePoint.Y, wellControl.ActualWidth, wellControl.ActualHeight));
var intersectionGeometry = Geometry.Combine(
selectionRectangle, controlRectangle, GeometryCombineMode.Intersect, null);
if (intersectionGeometry.GetArea() > 0)
{
wellControl.Command.Execute(this);
}
}
}
对您有用的完整链接:http://www.codeproject.com/Articles/354853/WPF-Organization-Chart-Hierarchy-MVVM-Application
当用户单击树中的节点时,我们需要让 ViewModel 节点知道选择已更改。我们喜欢将事件作为命令路由到 ViewModel