有趣的问题!正如您所说,一种方法是模拟 ItemsSource 集合。如:
<ListBox.ItemsSource>
<MultiBinding Converter="{StaticResource mockConverter}">
<Binding Path="YourCustomList" />
</MultiBinding>
</ListBox.ItemsSource>
请注意,我只使用了一个绑定的多重绑定。我相信这是让转换器“重新运行”的正确方法。这样,当您修改“YourCustomList”中的项目时,它将重新触发转换器。
与此不同,它只会触发一次转换器(当 ItemsSource 第一次绑定时)
<ListBox ItemsSource="{Binding YourCUstomList, Converter={StaticResource mockCOnverter}}" />
^ 如果添加新项目将不起作用。(转换器仅在 YourCustomList 属性更改时重新运行)
MockConverter 会很简单,只需确保生成带有分隔符的列表即可。你需要一个新的分隔符类。这样您就可以轻松使用 DataTemplates(DataType)。接下来,您可能必须在 ItemContainerStyle 中设置一个新触发器,以便在 object=Seperator 时设置 IsEnabled=false。
这将是相对无痛的,我没有看到任何并发症。这有点难看,因为分隔符不应该是 ListBoxItems。
也许这也可以工作。
您可以使用自己的覆盖 ListBox ItemsPanelTemplate。在您自己的模板中,您可以做任何您想做的事情。也许添加分隔符。这样,您就不会接触 ItemsSource。
查看 StackPanel.cs 的代码。我现在无法为您提供代码,但想法是这样的;您从 StackPanel 继承,并覆盖 Measure() 和 Arrange()。使用这些函数,您可以计算 stackPanel 应该有多大,并提供应该绘制分隔符的位置(X,y)。请注意,分隔符必须是 StackPanel 的子项,并且它们需要 IsHitTestVisible=False(因此它们不会生成事件)。
后来的解决方案需要时间,但是如果您正在学习 WPF,那为什么不呢?