コントロールが有効かどうかに関係なく、マウスカーソルの下にあるコントロールを検出しようとしています。
VisualTreeHelper.FindElementsInHostCoordinates
IsEnabled
プロパティが に設定されているコントロールを無視しますfalse
。この動作を変更する方法、または特定の画面位置でコントロールを見つける他の方法はありますか?
ありがとう。
コントロールが有効かどうかに関係なく、マウスカーソルの下にあるコントロールを検出しようとしています。
VisualTreeHelper.FindElementsInHostCoordinates
IsEnabled
プロパティが に設定されているコントロールを無視しますfalse
。この動作を変更する方法、または特定の画面位置でコントロールを見つける他の方法はありますか?
ありがとう。
独自の再帰メソッドを実装して、サブツリーを検索し、各要素をアプリケーションのルート ビジュアルに変換して「絶対」境界を取得し、「絶対」マウス ポイントがその領域内にあるかどうかをテストできます。
これはまさにあなたが必要としているものではないかもしれませんが、開始する必要があります。基本的にFindElementsInHostCoordinates
は同じ署名で置き換えたので、MouseMove ハンドラーで同じ方法で使用できます。このメソッドは、ヒット領域を計算するために ActualWidth と ActualHeight を知る必要があるため、FrameworkElements の「ヒット テスト」のみを試みます。
private IEnumerable<UIElement> FindAllElementsInHostCoordinates(Point intersectingPoint, UIElement subTree)
{
var results = new List<UIElement>();
int count = VisualTreeHelper.GetChildrenCount(subTree);
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(subTree, i) as FrameworkElement;
if (child != null)
{
GeneralTransform gt = child.TransformToVisual(Application.Current.RootVisual as UIElement);
Point offset = gt.Transform(new Point(0, 0));
Rect elementBounds = new Rect(offset.X, offset.Y, child.ActualWidth, child.ActualHeight);
if (IsInBounds(intersectingPoint, elementBounds))
{
results.Add(child as UIElement);
}
}
results.AddRange(FindAllElementsInHostCoordinates(intersectingPoint, child));
}
return results;
}
private bool IsInBounds(Point point, Rect bounds)
{
if (point.X > bounds.Left && point.X < bounds.Right &&
point.Y < bounds.Bottom && point.Y > bounds.Top)
{
return true;
}
return false;
}
次に、MouseMove ハンドラーから渡すポイントが に対して相対的であることを確認する必要がありますApplication.Current.RootVisual
。
IEnumerable<UIElement> elements = FindAllElementsInHostCoordinates(e.GetPosition(Application.Current.RootVisual), this);