首页 > 其他分享 >【WPF】自定义一个自删除的多功能ListBox

【WPF】自定义一个自删除的多功能ListBox

时间:2022-12-27 17:25:38浏览次数:78  
标签:界面 自定义 数据源 子项 支持 WPF ListBox

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

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

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

  1. 首先他支持等比拉伸,且数据分列显示。首先想到Grid的ColumnDefinitions可以满足。
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="74*" />
    <ColumnDefinition Width="179*" />
    <ColumnDefinition Width="157*" />
</Grid.ColumnDefinitions>
  1. 支持从界面去更改内部数据源,支持子项从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中绑定的数据源。

  1. 我们还需要把这个自定义的ListBoxItem放到我们自定义的ListBox中,让所有子项都应用这个自定义的ListboxItem,而不是默认的ListboxItem。代码如下:
internal class TestListBox : ListBox
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new TestItem();
    }
}
  1. 为了实现数据与标题分离的滚动效果,我单独将标题拿到外部,对标题进行单独显示,Listbox只显示数据。外部滑动条支持整体横向滑动,Listbox内部滑动条支持内部竖向滑动。给两个滑动条都加上最小宽度。
<ScrollViewer
            Grid.Row="1"
            Margin="0,20,0,0"
            HorizontalScrollBarVisibility="Auto"
            VerticalScrollBarVisibility="Disabled">
            <Border
                MinWidth="{Binding MinWidth, ElementName=listbox}"
                BorderBrush="#DFDFDF"
                BorderThickness="1">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="52" />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="79*" />
                        <ColumnDefinition Width="104*" />
                        <ColumnDefinition Width="80*" />
                    </Grid.ColumnDefinitions>
                    <Border Grid.ColumnSpan="20" Background="#F2F2F2" />
                    <TextBlock Text="ID" />
                    <TextBlock Grid.Column="1" Text="编号" />
                    <TextBlock Grid.Column="2" Text="操作" />
                    <controls:TestListBox
                        x:Name="listbox"
                        Grid.Row="1"
                        Grid.ColumnSpan="3"
                        MinWidth="1100"
                        ItemsSource="{Binding ItemsSourceData}"
                        Style="{StaticResource BaseListBoxStyle.WithOutHorizontalScrollViewer}" />
                </Grid>
            </Border>
        </ScrollViewer>

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

 <Style x:Key="BaseListBoxStyle.WithOutScrollViewer" TargetType="ListBox">
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Setter Property="ScrollViewer.CanContentScroll" Value="False" />
        <Setter Property="ScrollViewer.PanningMode" Value="Both" />
        <Setter Property="Stylus.IsFlicksEnabled" Value="False" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBox">
                    <Border
                        x:Name="Bd"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        SnapsToDevicePixels="true">
                        <ScrollViewer
                            Focusable="false"
                            HorizontalScrollBarVisibility="Disabled"
                            VerticalScrollBarVisibility="Auto">
                            <ItemsPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

标签:界面,自定义,数据源,子项,支持,WPF,ListBox
From: https://www.cnblogs.com/younShieh/p/17008534.html

相关文章

  • SpringBoot - 自定义拦截器HandlerInterceptor
    1.实现HandlerInterceptor接口/***自定义拦截器*/publicclassMyInterceptorimplementsHandlerInterceptor{@OverridepublicbooleanpreHandle(Htt......
  • Vue 封装自定义组件,通过npm install的方式安装使用
    1、新创建一个空的项目,我创建了一个新的项目(common-package-ui)2、在src下创建一个package文件夹用于存放自己的自定义组件,我创建了一个测试文件夹(test),下面创建了一个test......
  • QT打开摄像头(自定义取景器)
    自建取景器.h#ifndefCAMERASURFACE_H#defineCAMERASURFACE_H#include<QAbstractVideoSurface>#include<QObject>classCameraSurface:publicQAbstractVideoS......
  • Azure ARM (25) 自定义Role,不允许移动Azure资源
    《WindowsAzurePlatform系列文章目录》 我们把一个资源从资源组A移动到资源组B的时候,如果这时候有其他人对资源组A或者资源组B的时候,会遇到创建失败的错误,并......
  • 自定义elementUI皮肤、色系、主题、主色调
    ​​Element-Theworld'smostpopularVueUIframeworkElement,一套为开发者、设计师和产品经理准备的基于Vue2.0的桌面端组件库https://element.eleme.cn/#/zh-CN/th......
  • Vue按需引入注册UI以及自定义组件的封装
    1.单文件global注册自定义组件的封装importAfrom"../view/A.vue";importBfrom"../view/B.vue";constcomponents={A,B};exportdefault{install(Vue){......
  • 如何自定义小程序页面分享?
    步骤分解界面设置选中页面点击页面右侧图标点击界面设置设置值这样就可以实现自定义小程序页面分享了。......
  • Hive 自定义函数
    Hive自带了一些函数,比如:max/min等,但是数量有限,自己可以通过自定义UDF来方便的扩展。当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UD......
  • Java 自定义注解校验字段唯一性
    业务场景在项目中,某些情景下我们需要验证编码是否重复,账号是否重复,身份证号是否重复等...那么有没有办法可以解决这类似的重复代码量呢?我们可以通过自定义注解校验的方......
  • 一篇文章教你如何用界面组件DevExpress WPF为应用配置文件选择!
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专......