我自定义了一个列表框以显示饼图(每个Listitem是Pie的一个切片)。为此,我使用了Itemtemplate(现在)只包含Shape
。为了使这些形状形成一个完整的圆,我计算了每个部分的开始/结束,并使用自定义ItemsPanelTemplate
将项目堆叠在一起。
当我点击Pie附近的任何地方时,“last”项目会被选中,因为它位于其他项目的顶部。这很明显,但我希望因为ItemTemplate只包含一个Shape
,它会从那里继承命中测试而不是假设所有项都用矩形表示。
我应该在哪里加入hittesting?我想将IsHitTestVisible="false"
设置为我ItemTemplate
内的所有内容,除了形状外 - 但由于它除了我的形状之外实际上并不包含任何内容,因此我现在被卡住了。
修改
我尝试使用透明背景的网格围绕我的Shape
,我设置了IsHitTestVisible="false"
。这仍然导致在每次点击时选择最后一个元素,而我将假设不会选择任何内容。我想我可能会对hittesting应该如何工作感到困惑?
代码:
由于我是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>
答案 0 :(得分:0)
我终于找到了为什么测试不能按预期工作的原因:
ListBoxItem样式的默认模板围绕ContentPresenter
,其中Border
具有透明背景。所有点击事件都由该边框捕获并处理,而不是我的ContentPresenter
。根据Gaz的建议为ListBoxItem编写自己的样式并将背景设置为{x:null}
修复了问题(删除了边框,但我现在添加了另一个用于进一步自定义)。