【WPF】自定义一个自删除的多功能ListBox
阅读原文时间:2023年07月08日阅读:2

原文地址 https://www.cnblogs.com/younShieh/p/17008534.html

如果本文对你有所帮助,不妨点个关注和推荐呀,这是对笔者最大的支持~

我需要一个ListBox,他在界面上分为几列,每列对应一系列的数据。第一行是各数据的标题,支持横向滚动,竖向只支持数据源滚动,标题不随之滚动。视觉上与ListView类似。支持等比拉伸,支持多选,支持从界面去更改内部数据源,支持子项从ListBox中删除自己。为了实现这些功能,我决定自定义一个特殊的列表,当然他还是继承自ListBox。
  1. 首先他支持等比拉伸,且数据分列显示。首先想到Grid的ColumnDefinitions可以满足。

  2. 支持从界面去更改内部数据源,支持子项从ListBox中删除自己。

    为了从界面上满足功能,需要重写ItemContainerStyle样式,绘制出该子项Style。在Style中为了处理事件响应,可以通过在数据源子项中增加Command来对对应事件进行处理。但是处理逻辑可能有点繁杂,而且单从数据处理而言,子项无法从父项中删除自己,只能通过视觉树获取父ListBox,实现该功能。这样写的话代码耦合性会有点高,且数据处理时会调取界面处理。我希望数据源内部只是在处理数据,只能通过界面自上而下的访问数据源,而不是数据源和界面都有循环调用。

    第二种方法,我直接重写一个控件继承自ListBoxItem,将之前重写ItemContainerStyle样式复制到该控件前台,并在后台代码中对相应事件进行处理。代码如下:

    public partial class TestItem : ListBoxItem
    {
    public TestItem()
    {
    InitializeComponent();
    }

    private void Delete_Click(object sender, RoutedEventArgs e)
    {
    }

    }

    因为我是继承自ListBoxItem的,所以可以通过

    ItemsControl.ItemsControlFromItemContainer(this) is ListBox listBox

    方法获取到父listbox的对象,获取到父对象后,就可以从ListBox中删除自己。或是更改ListBox中绑定的数据源。

  3. 我们还需要把这个自定义的ListBoxItem放到我们自定义的ListBox中,让所有子项都应用这个自定义的ListboxItem,而不是默认的ListboxItem。代码如下:

    internal class TestListBox : ListBox
    {
    protected override DependencyObject GetContainerForItemOverride()
    {
    return new TestItem();
    }
    }

  4. 为了实现数据与标题分离的滚动效果,我单独将标题拿到外部,对标题进行单独显示,Listbox只显示数据。外部滑动条支持整体横向滑动,Listbox内部滑动条支持内部竖向滑动。给两个滑动条都加上最小宽度。

    在Listbox的样式中取消了横向滑动条的显示。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章