本文中所有代码都可以在github中查看,git版本中采用了master-dev的方式。在master中可以查看每一个demo的最后完成,在dev中可以查看每一步的代码。
github地址:git@github.com:kiwiwin/silverlight-demo.git。文件夹名称autocomplete-custom-searchmode-demo
1、AutoCompleteBox自定义数据Person
Person的定义:
public class Person
{
public String FirstName { get; set; }
public String SecondName { get; set; }
}
定义AutoCompleteBox:
<sdk:AutoCompleteBox Height="28" HorizontalAlignment="Center" x:Name="wordAutoCompleteBox" VerticalAlignment="Center" Width="200" />
初始化静态数据:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
wordAutoCompleteBox.ItemsSource = Persons();
}
private IEnumerable<Person> Persons()
{
var persons = new List<Person>();
persons.Add(new Person {FirstName = "java", SecondName = "china"});
persons.Add(new Person {FirstName = "csharp", SecondName = "japan"});
persons.Add(new Person {FirstName = "cplusplus", SecondName = "india"});
persons.Add(new Person {FirstName = "ruby", SecondName = "china"});
persons.Add(new Person {FirstName = "python", SecondName = "korea"});
return persons;
}
}
此时启动,在AutoCompleteBox中输入c不会有提示,这是因为AutoCompleteBox不知道如何显示,也不知道如何匹配:
定义Person的AutoCompleteBox中提示的显示方式,使用ItemTemplate。
<StackPanel x:Name="LayoutRoot" Background="White">
<sdk:AutoCompleteBox Height="28" HorizontalAlignment="Center" x:Name="wordAutoCompleteBox" VerticalAlignment="Center" Width="200" >
<sdk:AutoCompleteBox.ItemTemplate>
<DataTemplate>
<Grid Width="200">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Left" Foreground="Gray" Text="{Binding FirstName}" Grid.Column="0"/>
<TextBlock HorizontalAlignment="Left" Foreground="Gray" Text="{Binding SecondName}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</sdk:AutoCompleteBox.ItemTemplate>
</sdk:AutoCompleteBox>
自定义匹配规则是FirstName中含有已在AutoCompleteBox中输入的字符:
wordAutoCompleteBox.ItemFilter = (search, item) =>
{
Person person = item as Person;
if (person != null)
{
return person.FirstName.Contains(search);
}
return false;
};
此时,能够给出提示了,但是当选中其中某一个提示时,AutoCompleteBox显示的字符串变成了”autocomplete_custom_searchmode_demo.Person“。可以推测,这是因为Person缺少了ToString函数。
public override String ToString()
{
return FirstName + " " + SecondName;
}
添上以后,可以进行正确提示了。如下图
2、使用WebService更新AutoCompleteBox的ItemSource。
这里需要使用Populating事件,如果使用TextChanged等事件异步更新AutoCompleteBox将会失败。
关于Populating:
MSDN:http://msdn.microsoft.com/en-us/library/system.windows.controls.autocompletebox(v=vs.95).aspx
Populating的解释:Occurs when the AutoCompleteBox is populating the drop-down with possible matches based on theText property.
这里展示部分主要的代码,完整代码可以clone 我的git repository查看:
MainPage.xaml
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
wordAutoCompleteBox.ItemFilter = (search, item) =>
{
Person person = item as Person;
if (person != null)
{
return person.FirstName.Contains(search);
}
return false;
};
}
private void WordAutoCompleteBox_OnPopulating(object sender, PopulatingEventArgs e)
{
var client = new PersonServiceSoapClient();
client.GetPersonsCompleted += GetPersonsCompleted;
client.GetPersonsAsync();
}
private void GetPersonsCompleted(object sender, GetPersonsCompletedEventArgs e)
{
wordAutoCompleteBox.ItemsSource = e.Result;
wordAutoCompleteBox.PopulateComplete();
}
}
服务器端代码:
namespace autocomplete_custom_searchmode_demo.Web
{
/// <summary>
/// Summary description for PersonService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class PersonService : System.Web.Services.WebService
{
[WebMethod]
public List<Person> GetPersons()
{
return Persons();
}
private List<Person> Persons()
{
var persons = new List<Person>();
persons.Add(new Person { FirstName = "java", SecondName = "china" });
persons.Add(new Person { FirstName = "csharp", SecondName = "japan" });
persons.Add(new Person { FirstName = "cplusplus", SecondName = "india" });
persons.Add(new Person { FirstName = "ruby", SecondName = "china" });
persons.Add(new Person { FirstName = "python", SecondName = "korea" });
return persons;
}
}
[DataContract]
public class Person
{
[DataMember]
public String FirstName { get; set; }
[DataMember]
public String SecondName { get; set; }
public override String ToString()
{
return FirstName + " " + SecondName;
}
}
}
OK, done.