原文:
WPF Toolkit AutoCompleteBox 实体类绑定 关键字自定义关联搜索匹配
WPF Toolkit AutoCompleteBox 实体类绑定 关键字自定义关联搜索匹配
网上的例子都是零散的 翻阅了 很多篇文章后 再根据 自己项目的实际需求 整理出一个完整的 应用例子
汉字首字母全文匹配
提取绑定实体类相应的ID值
XAML
View Code
1 <Window xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit" x:Class="JiaXinTech.WPF.HotelTerminal.Test3" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="Test3" Height="300" Width="300" Loaded="Window_Loaded"> 5 <Grid> 6 7 <my:AutoCompleteBox HorizontalAlignment="Left" Margin="0,24,0,213" Name="autoCompleteBox1" Width="278" ItemsSource="{Binding}" > 8 <my:AutoCompleteBox.ItemTemplate> 9 <DataTemplate> 10 <StackPanel> 11 <TextBlock Text="{Binding Path=Name}"/> 12 </StackPanel> 13 </DataTemplate> 14 </my:AutoCompleteBox.ItemTemplate> 15 </my:AutoCompleteBox> 16 <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="92,126,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" /> 17 18 </Grid> 19 </Window>
C#
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Windows; 5 using System.Windows.Controls; 6 7 namespace JiaXinTech.WPF.HotelTerminal 8 { 9 /// <summary> 10 /// Test3.xaml 的交互逻辑 11 /// </summary> 12 public partial class Test3 : Window 13 { 14 public Test3() 15 { 16 InitializeComponent(); 17 } 18 private void Window_Loaded(object sender, RoutedEventArgs e) 19 { 20 List<CityEntity> cityEntity = new List<CityEntity>() { 21 new CityEntity(1,"北京","010"), 22 new CityEntity(2,"上海","021"), 23 new CityEntity(3,"天津","022"), 24 new CityEntity(4,"重庆","023"), 25 new CityEntity(6,"北海","000"), 26 new CityEntity(5,"香港","852") 27 }; 28 29 //投影出 CityEntity 实体类的 ID,Name 字段信息 30 var v = from lp in cityEntity 31 select new { lp.ID, lp.Name }; 32 33 34 autoCompleteBox1.DataContext = v.ToList(); 35 //AutoCompleteBox 要显示的字段名 36 autoCompleteBox1.ValueMemberPath = "Name"; 37 38 //当输入字符后延迟多少毫秒开始进行匹配,默认0 39 autoCompleteBox1.MinimumPopulateDelay = 100; 40 //最小输入的字符长度,当输入大于等于此长度时,才进行匹配,默认1 41 autoCompleteBox1.MinimumPrefixLength = 1; 42 //自定义匹配的模式,如果要实现自已的匹配方法,一定要设置为Custom,已预置了约13种方法 43 autoCompleteBox1.FilterMode = AutoCompleteFilterMode.Custom; 44 //填充前事件 动态赋值填充数据源数据 在这里编写 45 autoCompleteBox1.Populating += new PopulatingEventHandler(autoCompleteBox1_Populating); 46 //填充匹配操作 比如用汉字首字母匹配汉字 在这里编写代码 47 autoCompleteBox1.ItemFilter += ItemFilter; 48 49 } 50 51 void autoCompleteBox1_Populating(object sender, PopulatingEventArgs e) 52 { 53 e.Cancel = true;//一定要指定已处理此处理,取消此事件 54 55 //根据用户输入的字符串 动态从数据库中 提取相匹配的数据 56 List<CityEntity> cityEntity = new List<CityEntity>() { 57 new CityEntity(8,"北京1","001"), 58 new CityEntity(9,"北京2","002"), 59 new CityEntity(10,"北京3","003"), 60 new CityEntity(11,"北京4","004") 61 }; 62 63 var v = from lp in cityEntity 64 select new { lp.ID, lp.Name }; 65 66 autoCompleteBox1.DataContext = v.ToList(); 67 autoCompleteBox1.ValueMemberPath = "Name"; 68 69 autoCompleteBox1.PopulateComplete();//一定要指定填充完成,可以进行匹配操作,从而自动引发ItemFilter 事件 70 71 } 72 73 public bool ItemFilter(string search, object item) 74 { 75 //search 就是用户输入的关键字。 76 //item是就ItemSource中的项,本例是(object(string)),也可以复杂类型,但要求实现IEnumerable接口 77 //可以根据相应的逻辑再做进一步处理。为提高性能就在填充前对数据源作处理,此处仅为演示。 78 79 //要匹配的文本信息 80 string tbText = GetPropertyValue(item, "Name").ToString().ToLower(); 81 82 //原文本再拼接原文本的首字 83 tbText = tbText + GetFirstLetter(tbText).ToLower(); 84 85 //搜索匹配关键字 86 if (tbText.Contains(search.ToLower())) 87 { 88 return true;//返回True表示此项匹配,会出现在下拉选框中 89 } 90 return false; 91 } 92 93 private void button1_Click(object sender, RoutedEventArgs e) 94 { 95 if (autoCompleteBox1.SelectedItem != null) 96 { 97 //返回SelectedItem绑定的对象信息 98 object ci = (object)autoCompleteBox1.SelectedItem; 99 100 //输出绑定对象的ID信息 101 MessageBox.Show("您选中的内容ID是---" + GetPropertyValue(ci, "ID").ToString()); 102 103 } 104 } 105 106 ////微软的转换方法 比较简洁 //工具包下载地址http://www.microsoft.com/zh-cn/download/details.aspx?id=15251 107 ////using Microsoft.International.Converters.PinYinConverter; 108 ////using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter; 109 ///// <summary> 110 ///// 获取汉字首字母 111 ///// </summary> 112 ///// <param name="str"></param> 113 ///// <returns></returns> 114 //public static string GetPinYinInitial(string str) 115 //{ 116 // string r = string.Empty; 117 // foreach (char obj in str) 118 // { 119 // try 120 // { 121 // ChineseChar chineseChar = new ChineseChar(obj); 122 // string t = chineseChar.Pinyins[0].ToString(); 123 // r += t.Substring(0, 1); 124 // } 125 // catch 126 // { 127 // r += obj.ToString(); 128 // } 129 // } 130 // return r; 131 132 //} 133 134 #region 取中文首字母 135 136 public static string GetFirstLetter(string paramChinese) 137 { 138 139 string strTemp = ""; 140 141 int iLen = paramChinese.Length; 142 143 int i = 0; 144 145 146 147 for (i = 0; i <= iLen - 1; i++) 148 { 149 150 strTemp += GetCharSpellCode(paramChinese.Substring(i, 1)); 151 152 } 153 154 155 156 return strTemp; 157 158 159 160 } 161 162 163 164 /// <summary> 165 166 /// 得到一个汉字的拼音第一个字母,如果是一个英文字母则直接返回大写字母 167 168 /// </summary> 169 170 /// <param name="CnChar">单个汉字</param> 171 172 /// <returns>单个大写字母</returns> 173 174 private static string GetCharSpellCode(string paramChar) 175 { 176 177 long iCnChar; 178 179 180 181 byte[] ZW = System.Text.Encoding.Default.GetBytes(paramChar); 182 183 184 185 //如果是字母,则直接返回 186 187 if (ZW.Length == 1) 188 { 189 return paramChar.ToUpper(); 190 191 } 192 193 else 194 { 195 196 // get the array of byte from the single char 197 198 int i1 = (short)(ZW[0]); 199 200 int i2 = (short)(ZW[1]); 201 202 iCnChar = i1 * 256 + i2; 203 204 } 205 206 207 208 //expresstion 209 210 //table of the constant list 211 212 // 'A'; //45217..45252 213 214 // 'B'; //45253..45760 215 216 // 'C'; //45761..46317 217 218 // 'D'; //46318..46825 219 220 // 'E'; //46826..47009 221 222 // 'F'; //47010..47296 223 224 // 'G'; //47297..47613 225 226 227 228 // 'H'; //47614..48118 229 230 // 'J'; //48119..49061 231 232 // 'K'; //49062..49323 233 234 // 'L'; //49324..49895 235 236 // 'M'; //49896..50370 237 238 // 'N'; //50371..50613 239 240 // 'O'; //50614..50621 241 242 // 'P'; //50622..50905 243 244 // 'Q'; //50906..51386 245 246 247 248 // 'R'; //51387..51445 249 250 // 'S'; //51446..52217 251 252 // 'T'; //52218..52697 253 254 //没有U,V 255 256 // 'W'; //52698..52979 257 258 // 'X'; //52980..53640 259 260 // 'Y'; //53689..54480 261 262 // 'Z'; //54481..55289 263 264 265 266 // iCnChar match the constant 267 268 if ((iCnChar >= 45217) && (iCnChar <= 45252)) 269 { 270 271 return "A"; 272 273 } 274 275 else if ((iCnChar >= 45253) && (iCnChar <= 45760)) 276 { 277 278 return "B"; 279 280 } 281 282 else if ((iCnChar >= 45761) && (iCnChar <= 46317)) 283 { 284 285 return "C"; 286 287 } 288 289 else if ((iCnChar >= 46318) && (iCnChar <= 46825)) 290 { 291 292 return "D"; 293 294 } 295 296 else if ((iCnChar >= 46826) && (iCnChar <= 47009)) 297 { 298 299 return "E"; 300 301 } 302 303 else if ((iCnChar >= 47010) && (iCnChar <= 47296)) 304 { 305 306 return "F"; 307 308 } 309 310 else if ((iCnChar >= 47297) && (iCnChar <= 47613)) 311 { 312 313 return "G"; 314 315 } 316 317 else if ((iCnChar >= 47614) && (iCnChar <= 48118)) 318 { 319 320 return "H"; 321 322 } 323 324 else if ((iCnChar >= 48119) && (iCnChar <= 49061)) 325 { 326 327 return "J"; 328 329 } 330 331 else if ((iCnChar >= 49062) && (iCnChar <= 49323)) 332 { 333 return "K"; 334 335 } 336 337 else if ((iCnChar >= 49324) && (iCnChar <= 49895)) 338 { 339 340 return "L"; 341 342 } 343 344 else if ((iCnChar >= 49896) && (iCnChar <= 50370)) 345 { 346 347 return "M"; 348 349 } 350 351 352 353 else if ((iCnChar >= 50371) && (iCnChar <= 50613)) 354 { 355 356 return "N"; 357 358 } 359 360 else if ((iCnChar >= 50614) && (iCnChar <= 50621)) 361 { 362 363 return "O"; 364 365 } 366 367 else if ((iCnChar >= 50622) && (iCnChar <= 50905)) 368 { 369 370 return "P"; 371 372 } 373 374 else if ((iCnChar >= 50906) && (iCnChar <= 51386)) 375 { 376 377 return "Q"; 378 379 } 380 381 else if ((iCnChar >= 51387) && (iCnChar <= 51445)) 382 { 383 384 return "R"; 385 386 } 387 388 else if ((iCnChar >= 51446) && (iCnChar <= 52217)) 389 { 390 391 return "S"; 392 393 } 394 395 else if ((iCnChar >= 52218) && (iCnChar <= 52697)) 396 { 397 398 return "T"; 399 400 } 401 402 else if ((iCnChar >= 52698) && (iCnChar <= 52979)) 403 { 404 405 return "W"; 406 407 } 408 409 else if ((iCnChar >= 52980) && (iCnChar <= 53688)) 410 { 411 412 return "X"; 413 414 } 415 416 else if ((iCnChar >= 53689) && (iCnChar <= 54480)) 417 { 418 419 return "Y"; 420 421 } 422 423 else if ((iCnChar >= 54481) && (iCnChar <= 55289)) 424 { 425 426 return "Z"; 427 } 428 else return ("?"); 429 430 } 431 432 433 434 #endregion 435 436 437 /// <summary> 438 /// 获取一个类指定的属性值 439 /// </summary> 440 /// <param name="info">object对象</param> 441 /// <param name="field">属性名称</param> 442 /// <returns></returns> 443 public static object GetPropertyValue(object info, string field) 444 { 445 if (info == null) return null; 446 Type t = info.GetType(); 447 IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi; 448 return property.First().GetValue(info, null); 449 } 450 451 452 /// <summary> 453 /// 城市实体类 454 /// </summary> 455 public class CityEntity 456 { 457 /// <summary> 458 /// 城市ID 459 /// </summary> 460 public int ID { get; set; } 461 /// <summary> 462 /// 城市名称 463 /// </summary> 464 public string Name { get; set; } 465 /// <summary> 466 /// 城市编号 467 /// </summary> 468 public string Code { get; set; } 469 470 /// <summary> 471 /// 城市实体类构造函数 472 /// </summary> 473 /// <param name="id">城市ID</param> 474 /// <param name="name">城市名称</param> 475 /// <param name="code">城市编号</param> 476 public CityEntity(int id, string name, string code) 477 { 478 ID = id; 479 Name = name; 480 Code = code; 481 } 482 } 483 } 484 485 486 }