自定义自动完成控件开发

在最近一个月的工作中,一直在开发一个简单的文本框,它具有自定义的自动完成过滤功能。这个想法是受到GMail搜索功能的启发。这个自定义控件需要具备以下所有功能,以满足项目需求:

它必须非常容易使用,并且尽可能少地与项目代码集成。 它需要与WCF兼容。想法是,像GMail一样,创建一个分层应用程序,因此过滤功能需要在服务器端执行,然后通过WCF通道传输结果。 它需要过滤自定义数据(可以来自数据库或自定义列表),并在多个字段上进行搜索,就像GMail一样,并建议相似的结果。 所有过滤都需要以异步方式完成,因此将使用响应式库。 它需要与键盘和鼠标交互。 它需要强制用户从可用列表中选择一个项目。 它必须完全兼容项目中使用的MVVM模板。 它需要通知用户正在应用过滤,以及过滤完成时。 它需要让用户能够浏览结果列表并选择一个项目。 除了过滤代码之外,所有代码都需要封装在自定义控件内。 支持水印文本。 还需要能够在视图模型中选择一个默认选项,并在控件上反映出来。

在互联网上找到了几个示例源代码,但都没有满足上述所有点。没有编写整个代码。这个项目是基于这篇文章的优秀内容: 。 欢迎任何关于如何改进这段代码的建议。

几个月来,一直在将一个VB6应用程序迁移到新技术上。经过几周的网络冲浪和搜索,学习新技术,设法开始了项目。面临的一个问题是如何让用户从几个表中选择一个项目。例如,需要让用户为顾客订单选择一个顾客表中的顾客。这需要通过WCF通道完成。通常,会在客户端填充一个组合框,让用户选择一个,但这是低效的。这个想法是让用户输入一些数据(至少三个字符),以帮助过滤数据,并将可能的匹配项返回给最终用户。

使用代码

从XAML的角度来看,使用这个控件非常简单:

<Window x:Class="TextBoxAutoCompleteTest.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ac="clr-namespace:WpfAutoComplete.Controls;assembly=WpfAutoComplete" Title="Autocomplete Text Box Project" Height="300" Width="300"> <Grid> <StackPanel> <Label Content="This is an Autocomplete Textbox" /> <ac:TextBoxAutoComplete Name="autoTxtBoxEng" SearchDataProvider="{Binding Path=MySearchProviderEng}" SelectedListBoxValue="{Binding Path=PhraseNumber, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" WatermarkText="Type in filtering text here..." /> </StackPanel> </Grid> </Window>

关于代码的一些说明: SearchDataProvider属性是将用于数据过滤的类。该类需要实现ISearchDataProvider接口。 SelectedListBoxValue是可选的,指向VM上的属性,由控件更新。 WatermarkText是当没有输入时显示的文本。

这是一个简单的SearchDataProvider类的示例,使用字典作为示例:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TextBoxAutoCompleteTest { class MyDataProviderEng : WpfAutoComplete.ISearchDataProvider { public WpfAutoComplete.SearchResult DoSearch(string searchTerm) { return new WpfAutoComplete.SearchResult { SearchTerm = searchTerm, Results = dict.Where(item => item.Value.ToUpperInvariant().Contains(searchTerm.ToUpperInvariant())).ToDictionary(v => v.Key, v => v.Value) }; } public WpfAutoComplete.SearchResult SearchByKey(object Key) { return new WpfAutoComplete.SearchResult { SearchTerm = null, Results = dict.Where(item => item.Key.ToString() == Key.ToString()).ToDictionary(v => v.Key, v => v.Value) }; } private readonly Dictionary dict = new Dictionary { {1, "The badger knows something"}, {2, "Your head looks something like a pineapple"}, // ... 更多数据 }; } }

很容易将此代码适应于使用WCF服务进行过滤并返回可用选项,而不是预定义的字典。看看这个新的ISearchDataProvider实现:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Ohmio.Client.DataProviders { class DataProviderClientes : WpfAutoComplete.ISearchDataProvider { private OhmioService.OhmioServiceClient serviceClient = new OhmioService.OhmioServiceClient(); public WpfAutoComplete.SearchResult DoSearch(string searchTerm) { return new WpfAutoComplete.SearchResult { SearchTerm = searchTerm, Results = (serviceClient.EnumClientes(searchTerm.ToUpperInvariant())).ToDictionary(x => (object)x.Key, y => y.Descripcion) }; } public WpfAutoComplete.SearchResult SearchByKey(object Key) { return new WpfAutoComplete.SearchResult { SearchTerm = null, Results = (serviceClient.EnumClientes(Key.ToString())).ToDictionary(v => (object)v.Key, v => v.Descripcion) }; } } }

在这种情况下,使用了一个WCF服务,该服务有一个名为EnumClientes的方法。这个方法接受一个过滤参数,在数据库上执行过滤,然后返回一个List,该对象被转换为字典对象。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485