当前位置: 首页 > 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.dtcms.com/a/330811.html

相关文章:

  • RabbitMQ高级特性——消息确认、持久性、发送方确认、重试
  • 解锁Prompt秘籍:框架、技巧与指标全解析
  • 基于Django的福建省旅游数据分析与可视化系统【城市可换】
  • 《量子雷达》第4章 量子雷达的检测与估计 预习2025.8.14
  • 【51单片机学习】定时器、串口、LED点阵屏、DS1302实时时钟、蜂鸣器
  • 量子人工智能
  • Python训练营打卡Day32-神经网络的训练
  • Swift 数据类型全景解析(基础到高阶)
  • 按位运算的枚举在 Swift 里如何实现?
  • 《吃透 C++ 类和对象(中):拷贝构造函数与赋值运算符重载深度解析》
  • 【数据分享】2014-2023年长江流域 (0.05度)5.5km分辨率的每小时日光诱导叶绿素荧光SIF数据
  • Pytest自动化测试框架总结
  • iOS性能监控新方法多版本对比与趋势分析实战指南
  • C++进阶:特殊类
  • 手写MyBatis第16弹:泛型魔法应用:MyBatis如何破解List的运行时类型
  • 笔试——Day38
  • 根据图片远程地址复制图片内容,可以在富文本、word等文本里粘贴
  • word——删除最后一页空白页
  • Exif.js获取手机拍摄照片的经纬度
  • 【网络】TCP/UDP总结复盘
  • Unity人形角色IK优化指南
  • AI搜索优化专家孟庆涛:以技术温度重构“人机信息对话”新范式
  • 手机实时提取SIM卡打电话的信令声音-当前现状与思考
  • CICD-DevOps进阶-2
  • 提升工作效率的利器:GitHub Actions Checkout V5
  • 多种适用于 MCU 固件的 OTA 升级方案
  • Qt基本控件
  • 飞算JavaAI金融风控场景实践:从实时监测到智能决策的全链路安全防护
  • 西门子TIA-FOR循环多路PID控制器(PID_Compact)
  • VirtualBox虚拟机Ubuntu18.04安装hdl_localization保姆级教程