gpt4 book ai didi

wpf - 添加到 Canvas 的 HitTest 子控件不起作用

转载 作者:行者123 更新时间:2023-12-04 16:19:54 24 4
gpt4 key购买 nike

我正在尝试对在运行时添加到 Canvas 的一组用户控件进行 HitTest 。

我的 Canvas :

<Canvas x:Name="LayoutRoot" Background="White">
<Canvas x:Name="Carrier" Canvas.ZIndex="-1">
</Canvas>
</Canvas>

我的 Canvas 代码:

    public MainPage()
{
InitializeComponent();

var uiElement = new MyUserControl();
this.Carrier.Children.Add(uiElement);

MouseLeftButtonDown += MouseLeftButtonDownHandler;
}

private List<UIElement> HitSprite(Point p)
{
var hitElements =
VisualTreeHelper.FindElementsInHostCoordinates(p, this.Carrier) as List<UIElement>;

return hitElements.Count > 0 ? hitElements : null;
}

private void MouseLeftButtonDownHandler(object sender, MouseButtonEventArgs e)
{
var list = HitSprite(e.GetPosition(this.LayoutRoot));
}

我的用户控件:

<Canvas x:Name="Container" AllowDrop="True">
<StackPanel Name="Description" Height="65" Canvas.ZIndex="2" IsHitTestVisible="False">
<TextBlock Text="Testing" x:Name="Name" FontSize="12" FontWeight="Bold" HorizontalAlignment="Center" IsHitTestVisible="False"/>

<Border Background="Green">
<Image x:Name="Body" Stretch="None" Canvas.ZIndex="0" Height="20" Width="20">
</Image>
</Border>
</StackPanel>
</Canvas>

我为 GetPoint 和 FindElementsInHostCoordinates 尝试了 Carrier 和 LayoutRoot 的各种组合,但返回的元素始终为空。

我做错了什么?

最佳答案

关于 HitTest ,您必须注意以下几点:

  1. 没有背景的元素不会出现在 HitTest 中,所以设置背景,甚至设置为透明工作。发生这种情况是因为对象需要“坚固”才能进行 HitTest 。
  2. 没有宽度和高度的元素不会出现在 HitTest 中,因为它们没有要命中的主体。
  3. IsHitTestVisible=false 的元素不会出现在 HitTest 中,它们已被明确排除在 HitTest 之外。

在您的情况下,这些因素的组合使您的用户控件对 HitTest 不可见:

  1. 您的用户控件不可靠,没有背景。
  2. 在您的用户控件中用作布局根的 Canvas 没有设置大小,因此宽度和高度为零。它也没有背景。
  3. 用户控件中的所有子元素都有 IsHitTestVisible=false,这会将它们明确排除在 HitTest 之外。

我对您的用户控件 XAML 和后面的代码进行了一些修改,现在我在 HitTest 结果中看到了您的用户控件:

    public MainPage()
{
// Required to initialize variables
InitializeComponent();

var uiElement = new MyUserControl();
this.Carrier.Children.Add(uiElement);

MouseLeftButtonDown += MouseLeftButtonDownHandler;
}
private List<UIElement> HitSprite(Point p)
{
var hitElements =
VisualTreeHelper.FindElementsInHostCoordinates(p, this.LayoutRoot) as List<UIElement>;

return hitElements.Count > 0 ? hitElements : null;
}

private void MouseLeftButtonDownHandler(object sender, MouseButtonEventArgs e)
{
var list = HitSprite(e.GetPosition(this.LayoutRoot));
}

XAML:

<Grid x:Name="Container" AllowDrop="True" Background="Transparent">
<StackPanel Name="Description" Height="65" Canvas.ZIndex="2" IsHitTestVisible="False">
<TextBlock Text="Testing" x:Name="Name" FontSize="12" FontWeight="Bold" HorizontalAlignment="Center" IsHitTestVisible="False"/>

<Border Background="Green">
<Image x:Name="Body" Stretch="None" Canvas.ZIndex="0" Height="20" Width="20">
</Image>
</Border>
</StackPanel>
</Grid>

作为额外的建议,嵌套 Canvas 面板不是一个好主意,除非有特定的理由这样做。 Canvas 在很多方面都是一个特殊的面板,例如,它不会裁剪超出其边界的项目,默认情况下它没有大小,除非你设置一个,它不是一个实体对象,除非你明确设置背景.尝试使用 Grid 和 StackPanel 来排列对象,并使用 Canvas 仅在 (x,y) 坐标上进行特定定位。

关于wpf - 添加到 Canvas 的 HitTest 子控件不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6205637/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com