Silverlight中AutoCompleteBox异步更新自定义的ItemSource

本文分为两部分,第一部分演示如何在AutoCompleteBox使用自定义的数据类型和自定义的数据匹配方式,第二部分将演示当itemsource从webservice中异步获取时如何实现.

 本文中所有代码都可以在github中查看,git版本中采用了master-dev的方式。在master中可以查看每一个demo的最后完成,在dev中可以查看每一步的代码。
github地址:
[email protected]: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;
        }

添上以后,可以进行正确提示了。如下图

Silverlight中AutoCompleteBox异步更新自定义的ItemSource_第1张图片

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.

 

你可能感兴趣的:(Silverlight中AutoCompleteBox异步更新自定义的ItemSource)