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

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

 本文中所有代码都可以在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.

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值