我自定义了一个列表框来显示饼图(每个列表项都是饼图的一部分)。为此,我使用了一个 Itemtemplate,它(目前)仅包含一个 Shape
。为了使这些形状形成一个完整的圆,我计算了每 block 的开始/结束角度,并使用自定义 ItemsPanelTemplate
将项目堆叠在一起。
当我点击饼图附近的任何地方时,“最后一个”项目被选中,因为它位于其他项目之上。这很明显,但我希望因为 ItemTemplate 只包含一个 Shape
,它会从那里继承 HitTest ,而不是假设所有项目都由矩形表示。
我应该在哪里包含 HitTest ?我想将 IsHitTestVisible="false"
设置为我的 ItemTemplate
中的所有内容,形状除外 - 但由于它实际上不包含除我的形状之外的任何内容,我我现在卡住了。
编辑:
我尝试用具有透明背景的网格围绕我的 Shape
,我在其上设置了 IsHitTestVisible="false"
。这仍然会导致每次单击时选择最后一个元素,而我会假设不会选择任何内容。我想我可能对 HitTest 应该如何工作感到困惑?
代码:
由于我是 WPF 的新手,我可能在实现过程中遗漏了一些东西。我添加了一个最小示例的相关代码部分:
我的Shape
-类:
public class PiePiece : Shape
{
protected override Geometry DefiningGeometry
{
get { return GetPieGeometry() }
}
//some DependencyProperties and helper methods.
private Geometry GetPieGeometry()
{
//calculations
}
}
XAML:
<Window [...] xmlns:Runner="clr-namespace:MyNamespace">
<Window.Resources>
<!-- some custom converters -->
<!-- ListBox-Style with the custom ControlTemplate for my Listbox -->
<ItemsPanelTemplate x:Key="ItemPanel">
<Grid/>
</ItemsPanelTemplate>
</Window.Resources>
<ListBox [...] ItemsPanel="{StaticResource ItemPanel}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="{x:Null}" IsHitTestVisible="False">
<Runner:PiePiece IsHitTestVisible="False" [...]>
<!-- Dependency Properties are set via Multibinding here -->
</Runner:PiePiece>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
最佳答案
我终于找到了 HitTest 没有按预期工作的原因:
ListBoxItem-Style 的默认模板将 ContentPresenter
包围在带有透明背景的 Border
中。所有点击事件都由该边框捕获和处理,而不是我的 ContentPresenter
。按照 Gaz 的建议为 ListBoxItem 编写我自己的样式并将背景设置为 {x:null}
解决了这个问题(删除边框也是如此,但我现在添加了另一个边框以进行进一步自定义)。
关于c# - 对列表框中的列表项进行 HitTest ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30570306/