当前位置: 首页 > news >正文

.Net4.0 WPF中实现下拉框搜索效果

SearchableComboBox.xaml  前端页面代码如下:

    <UserControl x:Class="Test.Complexs.SearchableComboBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
mc:Ignorable="d" 
d:DesignHeight="30" d:DesignWidth="200">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

        <!-- 带搜索功能的下拉框容器 -->
<Grid x:Name="SearchableComboBox2" Width="250" Height="30">
<!-- 显示选中项的文本框 -->
<TextBox x:Name="mySelectedItemTextBox"  IsReadOnly="True"  Padding="5,0,30,0"   Background="White" BorderBrush="Silver" BorderThickness="1"/>

            <!-- 下拉按钮 -->
<ToggleButton x:Name="myDropDownButton"  Width="30"  Height="30"  HorizontalAlignment="Right" Click="myDropDownButton_Click">
<Path Fill="Black" Data="M 0 0 L 4 4 L 8 0 Z" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</ToggleButton>

            <!-- 下拉面板 -->
<Popup x:Name="myDropDownPopup"  Placement="Bottom"  PlacementTarget="{Binding ElementName=SearchableComboBox}"  AllowsTransparency="True" StaysOpen="False" Width="{Binding ActualWidth, ElementName=SearchableComboBox}">
<Border BorderBrush="Silver" BorderThickness="1" Background="White">
<StackPanel>
<!-- 搜索框 -->
<TextBox x:Name="mySearchTextBox"   Margin="5"  Padding="3"    BorderBrush="Silver"   BorderThickness="1"  TextChanged="mySearchTextBox_TextChanged" KeyDown="mySearchTextBox_KeyDown"  />

                        <!-- 下拉列表 -->
<ListBox x:Name="myItemsListBox"  Height="150"  Margin="0,0,0,5"  SelectionChanged="myItemsListBox_SelectionChanged"  MouseDoubleClick="myItemsListBox_MouseDoubleClick"/>
</StackPanel>
</Border>
</Popup>
</Grid>

        <TextBlock Grid.Row="1" Margin="0,20,0,0" Text="选中的内容将显示在上方输入框中" Foreground="Gray"/>
</Grid>

</UserControl>

SearchableComboBox.xaml.cs 后端代码如下:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

using System.Windows.Media;


namespace Test.Complexs
{
/// <summary>
/// SearchableComboBox.xaml 的交互逻辑
/// </summary>
public partial class SearchableComboBox : UserControl
{
// 原始数据源(实体类集合)
private List<City> _allCities;
// 过滤后的数据源
private ObservableCollection<City> _filteredCities;
// 当前选中的实体
private City _selectedCity;

        public SearchableComboBox()
{
InitializeComponent();

            // 初始化实体类数据
InitializeData();

            // 初始化过滤后的集合
_filteredCities = new ObservableCollection<City>(_allCities);
myItemsListBox.ItemsSource = _filteredCities;
}

        /// <summary>
/// 初始化实体类假数据
/// </summary>
private void InitializeData()
{
_allCities = new List<City>
{
new City(1, "北京"),
new City(2, "上海"),
new City(3, "广州"),
new City(4, "深圳"),
new City(5, "杭州"),
new City(6, "南京"),
new City(7, "成都"),
new City(8, "重庆"),
new City(9, "武汉"),
new City(10, "西安"),
new City(11, "苏州"),
new City(12, "郑州"),
new City(13, "青岛"),
new City(14, "长沙"),
new City(15, "天津")
};
}

        /// <summary>
/// 下拉按钮点击事件
/// </summary>
private void myDropDownButton_Click(object sender, RoutedEventArgs e)
{
// 切换下拉面板显示状态
myDropDownPopup.IsOpen = !myDropDownPopup.IsOpen;

            // 如果打开下拉面板,聚焦到搜索框
if (myDropDownPopup.IsOpen)
{
mySearchTextBox.Focus();
mySearchTextBox.Text = string.Empty;
}
}

        /// <summary>
/// 搜索框文本变化事件 - 实时过滤
/// </summary>
private void mySearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
FilterItems(mySearchTextBox.Text);
}

        /// <summary>
/// 根据搜索文本过滤实体类项目
/// </summary>
private void FilterItems(string searchText)
{
if (string.IsNullOrWhiteSpace(searchText))
{
// 搜索文本为空时显示所有项目
UpdateFilteredItems(_allCities);
}
else
{
// 过滤名称包含搜索文本的实体(不区分大小写)
var filtered = _allCities.Where(city =>
city.Name.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
UpdateFilteredItems(filtered);
}
}

        /// <summary>
/// 更新过滤后的列表
/// </summary>
private void UpdateFilteredItems(List<City> items)
{
_filteredCities.Clear();
foreach (var item in items)
{
_filteredCities.Add(item);
}
}

        /// <summary>
/// 列表项选择变化事件
/// </summary>
private void myItemsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (myItemsListBox.SelectedItem is City selectedCity)
{
// 保存选中的实体
_selectedCity = selectedCity;
// 回显选中项的名称
mySelectedItemTextBox.Text = selectedCity.Name;
// 可以在这里获取选中项的ID
// int selectedId = selectedCity.Id;
// 关闭下拉面板
myDropDownPopup.IsOpen = false;
// 清空选择,以便下次可以选择相同项
myItemsListBox.SelectedItem = null;
}
}

        /// <summary>
/// 列表项双击事件
/// </summary>
private void myItemsListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (myItemsListBox.SelectedItem is City selectedCity)
{
_selectedCity = selectedCity;
mySelectedItemTextBox.Text = selectedCity.Name;
myDropDownPopup.IsOpen = false;
myItemsListBox.SelectedItem = null;
}
}

        /// <summary>
/// 搜索框按键事件
/// </summary>
private void mySearchTextBox_KeyDown(object sender, KeyEventArgs e)
{
// 按Enter键选择第一个项目
if (e.Key == Key.Enter && _filteredCities.Count > 0)
{
_selectedCity = _filteredCities[0];
mySelectedItemTextBox.Text = _filteredCities[0].Name;
myDropDownPopup.IsOpen = false;
e.Handled = true;
}
// 按Esc键关闭下拉面板
else if (e.Key == Key.Escape)
{
myDropDownPopup.IsOpen = false;
e.Handled = true;
}
// 按向下箭头键聚焦到列表
else if (e.Key == Key.Down && _filteredCities.Count > 0)
{
myItemsListBox.Focus();
myItemsListBox.SelectedIndex = 0;
e.Handled = true;
}
}
}
/// <summary>
/// 城市实体类
/// </summary>
public class City
{
public int Id { get; set; }
public string Name { get; set; }

        public City(int id, string name)
{
Id = id;
Name = name;
}

        // 重写ToString方法,用于在列表中显示
public override string ToString()
{
return Name;
}
}

}

http://www.xdnf.cn/news/1295821.html

相关文章:

  • 面试题之项目中git如何进行管理
  • 如何启动本机mysql数据库
  • 在mysql> 下怎么运行 .sql脚本
  • XCTF-warmup详细题解(含思考过程)
  • Morph Studio-一站式AI视频创作平台
  • Vue浅学
  • Elasticsearch 中如何配置 RBAC 权限-实现安全的访问控制
  • QT6(创建第一个QT项目)
  • Win10上Qt使用Libcurl库
  • Qt 实现Ymodem协议源码分享
  • MySQL工具包中的其他程序
  • 从概率填充到置信度校准:GPT-5如何从底层重构AI的“诚实”机制
  • 树莓派 4B 上部署 Minecraft PaperMC 1.20.x 的一键部署脚本
  • ASQA: 面向模糊性事实问题的长格式问答数据集与评估框架
  • C#WPF实战出真汁02--登录界面设计
  • 利用 Python 爬虫按图搜索 1688 商品(拍立淘)实战指南
  • Windows批处理脚本自动合并当前目录下由You-get下载的未合并的音视频文件
  • LeetCode 分类刷题:2302. 统计得分小于 K 的子数组数目
  • 我的第一个开源项目-jenkins集成k8s项目
  • 开疆智能Ethernet转ModbusTCP网关连接UR机器人配置案例
  • 区块链 + 域名Web3时代域名投资的新风口(上)
  • 《算法导论》第 25 章:所有结点对的最短路径问题
  • 常见的tls检测的绕过方案
  • Mybatis学习笔记(二)
  • Transformer之多头注意力机制和位置编码(二)
  • vue更改style
  • 双椒派E2000D网络故障排查指南
  • 【Linux】库制作与原理
  • 2025年5月架构设计师综合知识真题回顾,附参考答案、解析及所涉知识点(三)
  • 苹果正计划大举进军人工智能硬件领域