• 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.

     

  • 相关阅读:
    【移动自动化】【三】控件定位
    【移动自动化】【二】Appium
    【自动化测试:笔记一】adb命令
    mysql api
    计算经纬度的正方形边界
    转 高效的多维空间点索引算法 — Geohash 和 Google S2
    转 为什么geometry+GIST 比 geohash+BTREE更适合空间搜索
    转 HBase GC日志
    转 HBase最佳实践-CMS GC调优
    转:HBase最佳实践-内存规划
  • 原文地址:https://www.cnblogs.com/java20130722/p/3206868.html
Copyright © 2020-2023  润新知