一个易用的 WPF 自动完成文本框 【已翻译100%】

介绍

这篇文章的目的是在社区中分享一些我上个月完成代码,让一个简单的文本框拥有自定义的自动完成过滤器。这个想法的灵感来自于GMail的搜索功能。在我的项目中,自定义的控件需要如下所有我需要的功能:

  • 它是容易使用的,集成到项目中时,需要的代码要尽量的少。
  • 它需要兼容WCF。我的想法是像GMail一样创建一个分层的应用,过滤功能需要在服务器端执行,然后将结果通过WCF通道传送。
  • 它需要过滤自定义数据(来自于数据库或者自定义的列表)并可搜索多个字段,像GMail一样,建议类似的结果。
  • 所有的过滤需要异步完成,因此我将使用Reactive库。
  • 需要和键盘及鼠标交互
  • 需要强制用户从可用的列表中选择一个选项
  • 完全兼容我项目中使用的MVVM模板
  • 需要通知用户过滤器已提交,当过滤完成时。
  • 需要让用户浏览结果列表,并选择一个选项。
  • 所有的代码,除了过滤代码都需要封装在自定义控件内
  • 水印文本支持
  • 我也需要有在内部视图模型选择默认选项的能力,并反映它在控件中。

我在网上发现了几个样例源码,但是全部都没有达到我上述的要求。我没有写全部的代码,我的代码是基于在这篇优秀的文章中介绍的项目。我接受所有关于怎样让这些代码更完善的建议。

背景

我已经花了几个月的时间在移植VB6应用程序到新技术上。经过几周的上网搜索以及学习新技术,我设法从我自己的项目开始。一个我面对的问题是,如何让用户从多个表格中选择一项。例如我需要让用户针对一个客户订单来从客户表格中选择一个客户。正常情况下我会在客户端的下拉列表框中填入所以的客户让用户自己选择一个,但是这个方法不高效。思路应该是让用户输入一些数据(至少三个字)来筛选数据,并返回可能的匹配结果给最终用户。

代码用例

从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<object, string> dict = new Dictionary<object, string> {
            { 1, "The badger knows something"},
            { 2, "Your head looks something like a pineapple"},
            { 3, "Crazy like a box of green frogs"},
            { 4, "The billiard table has green cloth"},
            { 5, "The sky is blue"},
            { 6, "We&apos;re going to need some golf shoes"},
            { 7, "This is going straight to the pool room"},
            { 8, "We&apos;re going to  Bonnie Doon"},
            { 9, "Spring forward - Fall back"},
            { 10, "Gerry had a plan which involved telling all"},
            { 11, "When is the summer coming"},
            { 12, "Take you time and tell me what you saw"},
            { 13, "All hands on deck"}
        };
    }
}

该代码可很简单地用于采用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

兴趣点

在写代码的过程中我学到很多。仍然有一些故障/缺失的特性是超越了我对代码实际的了解,特别是关于响应式程序库的:

  • 代码利用击键之间的延时来启动筛选过程。背后的思想是让筛选过程更有效率,而不是筛选在输入整个词后筛选。有时候控件会停止响应(插入文本不会执行筛选)。当它失去焦点敲入删除键或者回车键,筛选又开始工作。
  • 有效性: 当没有选项被选择的时候在控件边框画一个红色的框。我没有找到定制错误消息的方法。
  • 文本水印的颜色固定为淡灰色。当背景色是暗色的时候这是个问题。
  • 还没有多选功能。
时间: 2024-10-04 01:26:21

一个易用的 WPF 自动完成文本框 【已翻译100%】的相关文章

mfc-MFC一个关于自动滚动文本框的问题

问题描述 MFC一个关于自动滚动文本框的问题 在VCMFC中,向文本框追加文本文字,如何自动滚动文本框保持显示最后一行呢? 解决方案 m_edit.LineScroll(m_edit.GetLineCount()); 解决方案二: LineScroll + GetLineCount 就可以搞 解决方案三: 直接用Rich Eidt控件,不要用普通的edit控件,普通的也行,就是在属性里要设置一下自动换行

Android零基础入门第47节:自动完成文本框AutoCompleteTextView

原文:Android零基础入门第47节:自动完成文本框AutoCompleteTextView    上一期学习的Spinner的使用,掌握的怎么样?本期一起来学习AutoCompleteTextView的使用.     一.认识AutoCompleteTextView       AutoCompleteTextView是自动完成文本框,从EditText派生而出,实际上它也是一个文本编辑框,但它比普通编辑框多了一个功能:当用户输入一定字符之后,自动完成文本框会显示一个下拉菜单,供用户从中选择

【Android开发】高级组件-自动完成文本框

自动完成文本框(AutoCompleteTextView),用于实现允许用户输入一定字符后,显示一个下拉菜单,供用户从中选择,当用户选择某个选项之后,按用户选择自动填写该文本框. 语法格式: <AutoCompleteTextView 属性列表> </AutoCompleteTextView> AutoCompleteTextView组件继承EditText,所以它支持EditText组件提供的属性,同时,该组件还有以下属性: android:completionHint 下拉列表

Android AutoCompleteTextView自动提示文本框实例代码_Android

 自动提示文本框(AutoCompleteTextView)可以加强用户体验,缩短用户的输入时间(百度的搜索框就是这个效果). 先给大家展示下效果图,如果大家感觉还不错,请参考实现代码:   最后一张获取文本框里面的值(其实就跟TextView.EditText一样): 首先,在xml中定义AutoCompleteTextView控件: activity_main.xml: <LinearLayout xmlns:android="http://schemas.android.com/ap

Android自动编辑文本框(AutoCompleteTextView)使用方法详解

自动编辑文本框(AutoCompleteTextView)继承自EditText,能够接受用户的输入编辑,但是有这自己的特色功能:输入一定的字符以后会弹出下拉列表提示供用户选择,用户选择之后会自动填充文本框.这项功能正如浏览器的输入提示: 由于自动编辑文本框继承于EditText,它能够支持EditText的全部属性,但是在输入提示方面它有着自己的独特属性: android:completionHint     为弹出下拉菜单指定提示标题 android:completionThreshold 

Android AutoCompleteTextView自动提示文本框实例代码

自动提示文本框(AutoCompleteTextView)可以加强用户体验,缩短用户的输入时间(百度的搜索框就是这个效果). 先给大家展示下效果图,如果大家感觉还不错,请参考实现代码: 最后一张获取文本框里面的值(其实就跟TextView.EditText一样): 首先,在xml中定义AutoCompleteTextView控件: activity_main.xml: <LinearLayout xmlns:android="http://schemas.android.com/apk/r

自动完成文本框AutoCompleteTextView

自动完成文本框AutoCompleteTextView:用户输入一定字符后,会显示一个下拉菜单供用户选择 android:completionHint="请输入"设置出现在下拉菜单中的提示标题 android:dropDownHorizontalOffset="20dp"设置下拉菜单与文本框间的水平偏移,下拉菜单默认与文本框左对齐 android:completionThreshold="1"设置用户至少输入几个字符才会显示提示 android:

javaweb怎么样在点击按钮以后,弹出一个对话框,对话框里面要有文本框

问题描述 javaweb怎么样在点击按钮以后,弹出一个对话框,对话框里面要有文本框 例如当点击修改按钮以后,弹出一个对话框,里面有两个文本框还有一个保存按钮,如何实现这个功能 解决方案 你用div去模拟就行,或用第三方的遮罩 解决方案二: 用jquery ui dialog组件.或者用extjs 解决方案三: 具体看这里http://jqueryui.com/resources/demos/dialog/modal-form.html

急救 关于自动验证表单文本框 已输入的文字个数

问题描述 我做一个表单里面有一个文本框但是我想限定输入的文字长度每当用户输入文字的时候在文本框下方就自动的显示已输入的文字个数当输入的文字个数超过限定数就提示用户像这样的怎么做啊各位高手帮帮小弟啊谢谢 解决方案 解决方案二:关于文本框的限定字符个数你可以去看一下aip你新建一个JTextFieldtextField=newJTextField(20);好像这样的吧!!!解决方案三:用JavaScript的验证,然后alert解决方案四:publicclassExTextFieldextendsJ