【问题标题】:Can you insert items between ListBoxItems in a ListBox?您可以在 ListBox 中的 ListBoxItems 之间插入项目吗?
【发布时间】:2012-08-21 02:41:11
【问题描述】:

简单的问题。我们希望在水平样式列表框中的每个项目之间出现一个分隔线。想想 crumbtrail 中条目之间的箭头。但是,我们不希望该分隔符成为选择的一部分,因此它确实应该位于每个 ListBoxItem 之间。有可能吗?

我能想到的唯一两种方法是将“分隔符”项插入数据中并以不同的方式对其进行模板化,但这需要对项集合进行处理,而在数据绑定的情况下您可能无法做到这一点.

唯一的另一种方法是将实际的 ListBoxItem 设置为在突出显示边框之外有一个分隔符,然后将列表中的最后一个单独模板化。

谁能想到其他方法来做到这一点?

【问题讨论】:

    标签: wpf listbox controltemplate listboxitem separator


    【解决方案1】:

    DataTemplate 很好,我认为您在模拟项目集合时不会遇到问题。你为什么要你?

    <DataTemplate>
        <StackPanel Orientation="Horizontal">
          <Seperator/>
          <TextBlock Text="{Binding .}"/>
        </StackPanel/>
    </DataTemplate>
    

    我不会推荐您使用的最后一个选项。仅仅为了达到你想要的目的而将它分开是不对的。

    【讨论】:

    • 不确定您在此处显示的内容。而且,我的最后一个选项很容易通过使用&lt;DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}"&gt; 和在这种情况下隐藏分隔符的设置器来实现。这真的很容易。我只是讨厌分隔符是模板的一部分,因此它会收到点击等。
    • 如果您真的希望模板整洁,您可以这样做或使用装饰器?
    【解决方案2】:

    有趣的问题! 正如您所说,一种方法是模拟 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,那为什么不呢?

    【讨论】:

    • 真是个好主意...让面板做分隔符!甚至没有想到这一点。但是,我不确定您是否可以与面板的孩子混在一起,因为它们应该与绑定集合是一对一的,但话又说回来,也许它只是忽略了您手动添加的东西。也许我也可以通过渲染来做一些事情(但话说回来,我不认为面板支持渲染。)而且,如果你对 MultiBinding 在集合更改时重新触发是正确的,那是一个非常酷的提示!谢谢!投票给你,如果它有效,你也会得到答案。
    • 重温旧事,我可以肯定地说,在自定义面板中,孩子们不必与数据一对一。 (如果不是,跟踪所有内容只是一个b**ch,但可以做到!)即使没有,您也可以始终在 OnRender 方法中渲染分隔符,这样您就可以得到答案! :)
    猜你喜欢
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多