以下是一个简单的自定义下拉框类,包含分列、模糊查询和大量数据:

public class CustomComboBox : ComboBox
{
    private TextBox _searchBox;
    private ListView _listView;
    private GridView _gridView;

    public CustomComboBox()
    {
        // 创建搜索框和列表视图
        _searchBox = new TextBox();
        _listView = new ListView();
        _gridView = new GridView();

        // 设置搜索框样式
        _searchBox.Margin = new Thickness(2);
        _searchBox.TextChanged += SearchBox_TextChanged;

        // 设置列表视图样式
        _listView.Margin = new Thickness(2);
        _listView.View = _gridView;

        // 绑定下拉框的数据源和显示成员
        ItemsSource = GetData();
        DisplayMemberPath = 'Name';

        // 将搜索框和列表视图添加到下拉框中
        StackPanel stackPanel = new StackPanel();
        stackPanel.Children.Add(_searchBox);
        stackPanel.Children.Add(_listView);
        Popup popup = Template.FindName('PART_Popup', this) as Popup;
        popup.Child = stackPanel;
    }

    // 获取数据源
    private List<Item> GetData()
    {
        List<Item> items = new List<Item>();
        for (int i = 0; i < 10000; i++)
        {
            items.Add(new Item { Id = i, Name = 'Item ' + i });
        }
        return items;
    }

    // 模糊查询
    private void SearchBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        string searchText = _searchBox.Text.Trim().ToLower();
        if (searchText == '')
        {
            _listView.ItemsSource = ItemsSource;
            return;
        }

        List<Item> filteredItems = new List<Item>();
        foreach (Item item in ItemsSource)
        {
            if (item.Name.ToLower().Contains(searchText))
            {
                filteredItems.Add(item);
            }
        }
        _listView.ItemsSource = filteredItems;
    }

    // 分列
    public void AddColumn(string header, string bindingPath, int width)
    {
        GridViewColumn column = new GridViewColumn();
        column.Header = header;
        column.DisplayMemberBinding = new Binding(bindingPath);
        column.Width = width;
        _gridView.Columns.Add(column);
    }

    // 数据项类
    private class Item
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

使用方法:

<local:CustomComboBox Width='200' Height='30'>
    <local:CustomComboBox.Style>
        <Style TargetType='{x:Type local:CustomComboBox}'>
            <Setter Property='Template'>
                <Setter.Value>
                    <ControlTemplate TargetType='{x:Type local:CustomComboBox}'>
                        <Grid>
                            <ToggleButton x:Name='ToggleButton' Template='{StaticResource ComboBoxToggleButton}' Grid.Column='2' Focusable='false' IsChecked='{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}' ClickMode='Press'/>
                            <ContentPresenter x:Name='ContentSite' IsHitTestVisible='False' Content='{TemplateBinding SelectionBoxItem}' ContentTemplate='{TemplateBinding SelectionBoxItemTemplate}' ContentTemplateSelector='{TemplateBinding ItemTemplateSelector}' VerticalAlignment='Center' Margin='3,3,23,3' />
                            <TextBox x:Name='PART_EditableTextBox' Style='{x:Null}' Template='{StaticResource ComboBoxTextBox}' HorizontalAlignment='Left' VerticalAlignment='Bottom' Margin='3,3,23,3' Focusable='True' Background='Transparent' Visibility='Hidden' IsReadOnly='{TemplateBinding IsReadOnly}'/>
                            <Popup x:Name='Popup' Placement='Bottom' IsOpen='{TemplateBinding IsDropDownOpen}' AllowsTransparency='True' Focusable='False' PopupAnimation='Slide'>
                                <Grid x:Name='DropDown' SnapsToDevicePixels='True' MinWidth='{TemplateBinding ActualWidth}' MaxHeight='{TemplateBinding MaxDropDownHeight}'>
                                    <Border x:Name='DropDownBorder' Background='{StaticResource WindowBackgroundBrush}' BorderThickness='1' BorderBrush='{StaticResource SolidBorderBrush}'/>
                                    <ScrollViewer Margin='4,6,4,6' SnapsToDevicePixels='True'>
                                        <StackPanel IsItemsHost='True' KeyboardNavigation.DirectionalNavigation='Contained'/>
                                    </ScrollViewer>
                                </Grid>
                            </Popup>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property='IsEnabled' Value='False'>
                                <Setter TargetName='PART_EditableTextBox' Property='Foreground' Value='{StaticResource DisabledForegroundBrush}'/>
                            </Trigger>
                            <Trigger Property='IsGrouping' Value='True'>
                                <Setter Property='ScrollViewer.CanContentScroll' Value='False'/>
                            </Trigger>
                            <Trigger SourceName='Popup' Property='Popup.AllowsTransparency' Value='True'>
                                <Setter TargetName='DropDownBorder' Property='CornerRadius' Value='4'/>
                                <Setter TargetName='DropDownBorder' Property='Margin' Value='0,2,0,0'/>
                            </Trigger>
                            <Trigger Property='IsEditable' Value='True'>
                                <Setter Property='IsTabStop' Value='False'/>
                                <Setter TargetName='PART_EditableTextBox' Property='Visibility' Value='Visible'/>
                                <Setter TargetName='ContentSite' Property='Visibility' Value='Hidden'/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </local:CustomComboBox.Style>
</local:CustomComboBox>

添加分列:

customComboBox.AddColumn('ID', 'Id', 50);
customComboBox.AddColumn('Name', 'Name', 150);
WPF 高性能自定义下拉框:分列、模糊查询、支持数万行数据

原文地址: https://www.cveoy.top/t/topic/kqTP 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录