该控件的功能就是完成类似于google,或baidu中的搜索输入框的提示(选项)等功能,如下图所示:
下面是AutoCompleteBox的运行效果图:
好的,下面就简要介绍一下这个控件的使用方法:
首先,我们要新创建一个Silverlight的Application项目,然后要准备一个数据源,也就是当我们输入内容时,弹出的下拉列表框(这里就暂且这么说吧)中显示的相似的提示信息,这里为了方便起见,我直接用其源码示例中的硬编码类来表示数据源,当然后面还会介绍如何使用WCF来加载数据源信息,这里先创建一个Employee(雇员信息)类,如下:
Code
我们从代码中看到,Employee类的静态属性“AllExecutives”最终被绑定在SampleEmployeeCollection构造方法中。
接着为了能够在XAML文件中使用AutoCompleteBox控件,还需要添加相应的DLL引用(请从下载源码包中获取相应的DLL文件并引用到项目中来),如下图所示:
完成了这一步之后,就是将相应的NameSpace添加到XAML的头部,以便于在XAML文件中进行控件定义,如下:
接下来就是引用相应的数据源信息了,如下(SampleEmployeeCollection就是上面CS代码中的雇员信息类):
这时该轮到AutoCompleteBox“闪亮登场”了:
我们运行一下,看看效果怎么样:
代码很简单,不是吗?下面接着介绍一下上面有关该控件的两个属性:
当然如果将该属性设置为False时,则该控件在显示下拉列表时将不在输入框中设置第一条记录信息。这里为了提高一下难度,我们将会自定义一下“提示框”的样式,代码如下(注意其中的AutoCompleteBox.ItemTemplate部分代码):
该控件的运行效果如下图所示:
当然,该控件的模版方式还支持外部声明定义,并在控件内部进行引用(通过属性ItemTemplate绑定),下面首先是样式模版的定义:
下面是将上述模版绑定到当前AutoCompleteBox挖件的声明代码(注意相应的ItemTemplate属性):
其运行的效果如下图所示:
当然上面的控件声明代码中又引入了两个重要的属性,即:
上面所演示的三种情况基本上就可以满足我们的日常开发需要了。当然该控件还提供了不少事件,方法属性,来提供更高级的使用方式:
1.对已输入的数据信息进行下拉列表数据自定义的事件。比如该控件提供了Populating来进行相应处理,比如我们在XAML中定义如下代码:
然后在后台的CS代码中进行下面的事件绑定:
其相应的事件处理代码如下:
这时我们运行一下看看效果:
2.在其它控件(Datagrid)中嵌入该控件,代码如下(注意controls:AutoCompleteBox部分):
其运行如下图所示:
最后,我们将话题深入一下,看看如何使用wcf来获取相应的下拉列表数据项。当然这里还是用到了之前讲过的事件“Populating”,不过之前我们还要先创建一个silverlight wcf,如下:
当然,我们在WCF端还是用到了之前创建的Employee类文件(当然为了避免冲突改名为:EmployeeInfo)。另外在服务方法上使用下面代码来实现数据访问:
通过添加WEB服务引用的方式,系统会为我们创建相应的代码类文件,这里就不多说了。下面是Silverlight端的程序代码:
相应的返回数据事件处理代码如下:
运行时的效果如下图所示:
当然这里会有一个问题,就是当我对上面的代码“acb.ItemsSource = employeeStrList;”换成:
“acb.ItemsSource = e.Result;”之后,会出现在下面列表中显示的数据是该类的类型type信息,我想这可能是该控件的一个BUG,即在异步情况下进行数据(源)绑定时信息类型不正确。当然如果您知道是什么问题并有解决方案的话,不妨通过我,这里表示感谢了。

下面是AutoCompleteBox的运行效果图:

好的,下面就简要介绍一下这个控件的使用方法:
首先,我们要新创建一个Silverlight的Application项目,然后要准备一个数据源,也就是当我们输入内容时,弹出的下拉列表框(这里就暂且这么说吧)中显示的相似的提示信息,这里为了方便起见,我直接用其源码示例中的硬编码类来表示数据源,当然后面还会介绍如何使用WCF来加载数据源信息,这里先创建一个Employee(雇员信息)类,如下:

我们从代码中看到,Employee类的静态属性“AllExecutives”最终被绑定在SampleEmployeeCollection构造方法中。
接着为了能够在XAML文件中使用AutoCompleteBox控件,还需要添加相应的DLL引用(请从下载源码包中获取相应的DLL文件并引用到项目中来),如下图所示:

完成了这一步之后,就是将相应的NameSpace添加到XAML的头部,以便于在XAML文件中进行控件定义,如下:
xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
接下来就是引用相应的数据源信息了,如下(SampleEmployeeCollection就是上面CS代码中的雇员信息类):
<
UserControl.Resources
>
< samples:SampleEmployeeCollection x:Key ="SampleEmployees" />
</ UserControl.Resources >
< samples:SampleEmployeeCollection x:Key ="SampleEmployees" />
</ UserControl.Resources >
这时该轮到AutoCompleteBox“闪亮登场”了:
<
controls:AutoCompleteBox
x:Name
="autoComplete1"
IsTextCompletionEnabled
="True"
Width
="200"
Height
="25"
Grid.Row
="0"
Grid.Column ="1" Margin ="0+0,8+8" HorizontalAlignment ="Left" ItemsSource =" {StaticResource SampleEmployees} " />
Grid.Column ="1" Margin ="0+0,8+8" HorizontalAlignment ="Left" ItemsSource =" {StaticResource SampleEmployees} " />
我们运行一下,看看效果怎么样:

代码很简单,不是吗?下面接着介绍一下上面有关该控件的两个属性:
IsTextCompletionEnabled:该属性为True时,用于将当前被查询到的第一条记录的信息暂时放在控件的输入框中(text属性),上图中已看到。
ItemsSource:用于绑定相应的数据源信息({StaticResource SampleEmployees})
ItemsSource:用于绑定相应的数据源信息({StaticResource SampleEmployees})
当然如果将该属性设置为False时,则该控件在显示下拉列表时将不在输入框中设置第一条记录信息。这里为了提高一下难度,我们将会自定义一下“提示框”的样式,代码如下(注意其中的AutoCompleteBox.ItemTemplate部分代码):
<
controls:AutoCompleteBox
x:Name
="autoComplete2"
IsTextCompletionEnabled
="False"
Width
="200"
Height
="25"
Grid.Row
="1"
Grid.Column ="1" Margin ="0+0,8+8" HorizontalAlignment ="Left" ItemsSource =" {StaticResource SampleEmployees} " >
< controls:AutoCompleteBox.ItemTemplate >
< DataTemplate >
< Grid Width ="200" >
< Grid.ColumnDefinitions >
< ColumnDefinition Width ="100" />
< ColumnDefinition Width ="100" />
</ Grid.ColumnDefinitions >
< TextBlock HorizontalAlignment ="Left" Foreground ="Gray" Text =" {Binding FirstName} " Grid.Column ="0" />
< TextBlock HorizontalAlignment ="Left" Foreground ="Gray" Text =" {Binding LastName} " Grid.Column ="1" />
</ Grid >
</ DataTemplate >
</ controls:AutoCompleteBox.ItemTemplate >
</ controls:AutoCompleteBox >
Grid.Column ="1" Margin ="0+0,8+8" HorizontalAlignment ="Left" ItemsSource =" {StaticResource SampleEmployees} " >
< controls:AutoCompleteBox.ItemTemplate >
< DataTemplate >
< Grid Width ="200" >
< Grid.ColumnDefinitions >
< ColumnDefinition Width ="100" />
< ColumnDefinition Width ="100" />
</ Grid.ColumnDefinitions >
< TextBlock HorizontalAlignment ="Left" Foreground ="Gray" Text =" {Binding FirstName} " Grid.Column ="0" />
< TextBlock HorizontalAlignment ="Left" Foreground ="Gray" Text =" {Binding LastName} " Grid.Column ="1" />
</ Grid >
</ DataTemplate >
</ controls:AutoCompleteBox.ItemTemplate >
</ controls:AutoCompleteBox >
该控件的运行效果如下图所示:

当然,该控件的模版方式还支持外部声明定义,并在控件内部进行引用(通过属性ItemTemplate绑定),下面首先是样式模版的定义:
<
StackPanel.Resources
>
< DataTemplate x:Key ="EmployeeDataTemplate" >
< Grid Width ="200" >
< Grid.Background >
< SolidColorBrush Color ="Blue" />
</ Grid.Background >
< TextBlock Foreground ="#22ffffff" Margin ="0+0,8+8" FontSize ="14" Text =" {Binding DisplayName} " />
< StackPanel HorizontalAlignment ="Right" Margin ="0+0,8+8" >
< TextBlock HorizontalAlignment ="Right" Foreground ="White"
Text =" {Binding FirstName} " Padding ="2" />
< TextBlock HorizontalAlignment ="Right" Foreground ="White"
FontSize ="12" Text =" {Binding LastName} " Padding ="2" />
</ StackPanel >
</ Grid >
</ DataTemplate >
</ StackPanel.Resources >
< DataTemplate x:Key ="EmployeeDataTemplate" >
< Grid Width ="200" >
< Grid.Background >
< SolidColorBrush Color ="Blue" />
</ Grid.Background >
< TextBlock Foreground ="#22ffffff" Margin ="0+0,8+8" FontSize ="14" Text =" {Binding DisplayName} " />
< StackPanel HorizontalAlignment ="Right" Margin ="0+0,8+8" >
< TextBlock HorizontalAlignment ="Right" Foreground ="White"
Text =" {Binding FirstName} " Padding ="2" />
< TextBlock HorizontalAlignment ="Right" Foreground ="White"
FontSize ="12" Text =" {Binding LastName} " Padding ="2" />
</ StackPanel >
</ Grid >
</ DataTemplate >
</ StackPanel.Resources >
下面是将上述模版绑定到当前AutoCompleteBox挖件的声明代码(注意相应的ItemTemplate属性):
<
controls:AutoCompleteBox
x:Name
="ArrivalAirport"
MinimumPrefixLength ="1" SearchMode ="StartsWithCaseSensitive"
IsTextCompletionEnabled ="False"
Width ="228" Height ="25"
HorizontalAlignment ="Left" Margin ="0+0,8+8"
ItemsSource =" {StaticResource SampleEmployees} "
ItemTemplate =" {StaticResource EmployeeDataTemplate} " />
MinimumPrefixLength ="1" SearchMode ="StartsWithCaseSensitive"
IsTextCompletionEnabled ="False"
Width ="228" Height ="25"
HorizontalAlignment ="Left" Margin ="0+0,8+8"
ItemsSource =" {StaticResource SampleEmployees} "
ItemTemplate =" {StaticResource EmployeeDataTemplate} " />
其运行的效果如下图所示:

当然上面的控件声明代码中又引入了两个重要的属性,即:
SearchMode:查询方式,其提供了对当前已输入字符的查询方式,有如下几种枚举值:
StartsWithCaseSensitive:以大写已输入字符方式开始。
StartsWith:以已输入字符开始(不区别大小写)。
Contains:是否包含已输入字符
ContainsCaseSensitive:是否包含已输入大写字符.
Equals:是否字符相等
EqualsCaseSensitive:是否大写字符相等
.
MinimumPrefixLength:用于当输入的字符串达到该属性值时,才显示下拉列表框。
StartsWithCaseSensitive:以大写已输入字符方式开始。
StartsWith:以已输入字符开始(不区别大小写)。
Contains:是否包含已输入字符
ContainsCaseSensitive:是否包含已输入大写字符.
Equals:是否字符相等
EqualsCaseSensitive:是否大写字符相等

MinimumPrefixLength:用于当输入的字符串达到该属性值时,才显示下拉列表框。
上面所演示的三种情况基本上就可以满足我们的日常开发需要了。当然该控件还提供了不少事件,方法属性,来提供更高级的使用方式:
1.对已输入的数据信息进行下拉列表数据自定义的事件。比如该控件提供了Populating来进行相应处理,比如我们在XAML中定义如下代码:
<
controls:AutoCompleteBox
x:Name
="NowAutoComplete"
SearchMode
="None"
Width
="200"
Height
="25"
Grid.Column
="1"
IsTextCompletionEnabled ="True" Grid.Row ="3" HorizontalAlignment ="Left" Margin ="0+0,0+12" />
IsTextCompletionEnabled ="True" Grid.Row ="3" HorizontalAlignment ="Left" Margin ="0+0,0+12" />
然后在后台的CS代码中进行下面的事件绑定:
NowAutoComplete.Populating
+=
OnPopulatingSynchronous;
其相应的事件处理代码如下:
private
void
OnPopulatingSynchronous(
object
sender, PopulatingEventArgs e)
{
AutoCompleteBox source = (AutoCompleteBox)sender;
source.ItemsSource = new string []
{
e.Parameter + " 后续内容1 " ,
e.Parameter + " 后续内容2 " ,
e.Parameter + " 后续内容3 " ,
};
}
{
AutoCompleteBox source = (AutoCompleteBox)sender;
source.ItemsSource = new string []
{
e.Parameter + " 后续内容1 " ,
e.Parameter + " 后续内容2 " ,
e.Parameter + " 后续内容3 " ,
};
}
这时我们运行一下看看效果:

2.在其它控件(Datagrid)中嵌入该控件,代码如下(注意controls:AutoCompleteBox部分):
<
data:DataGrid
x:Name
="MyDataGrid"
AutoGenerateColumns
="False"
Grid.Column
="1"
Width
="290"
Grid.Row
="5"
Margin ="0+0,0+8" ItemsSource =" {StaticResource SampleEmployees} " >
< data:DataGrid.Columns >
< data:DataGridTemplateColumn Header ="DisplayName" >
< data:DataGridTemplateColumn.CellEditingTemplate >
< DataTemplate >
< controls:AutoCompleteBox HorizontalAlignment ="Left" Width ="180" IsTabStop ="True"
ItemsSource =" {StaticResource SampleEmployees} "
Text =" {Binding DisplayName, Mode=TwoWay} " />
</ DataTemplate >
</ data:DataGridTemplateColumn.CellEditingTemplate >
</ data:DataGridTemplateColumn >
< data:DataGridTextColumn Binding =" {Binding FirstName} " Header ="FirstName" />
</ data:DataGrid.Columns >
</ data:DataGrid >
Margin ="0+0,0+8" ItemsSource =" {StaticResource SampleEmployees} " >
< data:DataGrid.Columns >
< data:DataGridTemplateColumn Header ="DisplayName" >
< data:DataGridTemplateColumn.CellEditingTemplate >
< DataTemplate >
< controls:AutoCompleteBox HorizontalAlignment ="Left" Width ="180" IsTabStop ="True"
ItemsSource =" {StaticResource SampleEmployees} "
Text =" {Binding DisplayName, Mode=TwoWay} " />
</ DataTemplate >
</ data:DataGridTemplateColumn.CellEditingTemplate >
</ data:DataGridTemplateColumn >
< data:DataGridTextColumn Binding =" {Binding FirstName} " Header ="FirstName" />
</ data:DataGrid.Columns >
</ data:DataGrid >
其运行如下图所示:

最后,我们将话题深入一下,看看如何使用wcf来获取相应的下拉列表数据项。当然这里还是用到了之前讲过的事件“Populating”,不过之前我们还要先创建一个silverlight wcf,如下:

当然,我们在WCF端还是用到了之前创建的Employee类文件(当然为了避免冲突改名为:EmployeeInfo)。另外在服务方法上使用下面代码来实现数据访问:
[ServiceContract(Namespace
=
""
)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class AutoCompletedService
{
[OperationContract]
public List < EmployeeInfo > GetEmployeeCollection( string name)
{
List < EmployeeInfo > EmpolyeeList = new List < EmployeeInfo > ();
foreach (EmployeeInfo ei in (from employeeinfo in EmployeeInfo.AllExecutives
where employeeinfo.DisplayName.StartsWith(name)
select employeeinfo))
{
EmpolyeeList.Add(ei);
}
return EmpolyeeList;
}
}
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class AutoCompletedService
{
[OperationContract]
public List < EmployeeInfo > GetEmployeeCollection( string name)
{
List < EmployeeInfo > EmpolyeeList = new List < EmployeeInfo > ();
foreach (EmployeeInfo ei in (from employeeinfo in EmployeeInfo.AllExecutives
where employeeinfo.DisplayName.StartsWith(name)
select employeeinfo))
{
EmpolyeeList.Add(ei);
}
return EmpolyeeList;
}
}
通过添加WEB服务引用的方式,系统会为我们创建相应的代码类文件,这里就不多说了。下面是Silverlight端的程序代码:
void
Page_Loaded(
object
sender, RoutedEventArgs e)
{
WCFAutoComplete.IsTextCompletionEnabled = false ;
WCFAutoComplete.SearchMode = AutoCompleteSearchMode.None;
WCFAutoComplete.Populating += (s, args) =>
{
args.Cancel = true ;
AutoCompletedServiceClient acsc = new AutoCompletedServiceClient();
acsc.GetEmployeeCollectionCompleted += new EventHandler < GetEmployeeCollectionCompletedEventArgs >
(acsc_GetEmployeeCollectionCompleted);
acsc.GetEmployeeCollectionAsync(args.Parameter, s);
};
}
{
WCFAutoComplete.IsTextCompletionEnabled = false ;
WCFAutoComplete.SearchMode = AutoCompleteSearchMode.None;
WCFAutoComplete.Populating += (s, args) =>
{
args.Cancel = true ;
AutoCompletedServiceClient acsc = new AutoCompletedServiceClient();
acsc.GetEmployeeCollectionCompleted += new EventHandler < GetEmployeeCollectionCompletedEventArgs >
(acsc_GetEmployeeCollectionCompleted);
acsc.GetEmployeeCollectionAsync(args.Parameter, s);
};
}
相应的返回数据事件处理代码如下:
void
acsc_GetEmployeeCollectionCompleted(
object
sender, GetEmployeeCollectionCompletedEventArgs e)
{
AutoCompleteBox acb = e.UserState as AutoCompleteBox;
if (acb != null && e.Error == null && ! e.Cancelled)
{
if (e.Result.Count > 0 )
{
List < string > employeeStrList = new List < string > ();
foreach (EmployeeInfo employeeinfo in e.Result)
{
employeeStrList.Add(employeeinfo.FirstName + " " + employeeinfo.LastName);
}
acb.ItemsSource = employeeStrList;
acb.PopulateComplete();
}
}
}
{
AutoCompleteBox acb = e.UserState as AutoCompleteBox;
if (acb != null && e.Error == null && ! e.Cancelled)
{
if (e.Result.Count > 0 )
{
List < string > employeeStrList = new List < string > ();
foreach (EmployeeInfo employeeinfo in e.Result)
{
employeeStrList.Add(employeeinfo.FirstName + " " + employeeinfo.LastName);
}
acb.ItemsSource = employeeStrList;
acb.PopulateComplete();
}
}
}
运行时的效果如下图所示:

当然这里会有一个问题,就是当我对上面的代码“acb.ItemsSource = employeeStrList;”换成:
“acb.ItemsSource = e.Result;”之后,会出现在下面列表中显示的数据是该类的类型type信息,我想这可能是该控件的一个BUG,即在异步情况下进行数据(源)绑定时信息类型不正确。当然如果您知道是什么问题并有解决方案的话,不妨通过我,这里表示感谢了。
好了,今天的内容就先到这里了,源码下载,请点击这里。
本文转自 daizhenjun 51CTO博客,原文链接:http://blog.51cto.com/daizhj/124380,如需转载请自行联系原作者