Toolkit裡的AutoCompletedBox預設的功能已經很強大了,做一個英文城市或者英文單詞的提示,可以直接指定FilterMode為AutoCompleteFilterMode.SartsWith(或者其它更合適的過濾器)。
對於內建的FilterMode,請參見MSDN:http://msdn.microsoft.com/zh-cn/library/system.windows.controls.autocompletefiltermode(VS.95).aspx
但是對於中文城市名稱過濾來說,恐怕還需要進一步修改。原因如下,由於我們的使用者使用的輸入可能是中文鍵盤,舉一個很簡單的例子來說:使用者想找“北京”的時候,他輸入[beijing,bei,b,北]都是需要提示的,注意,最後那個是中文,這個時候,就需要親手來寫一些代碼啦。
先上個:
首先是Model類
public class CityModel:BaseModel{private string _cityName = "";private string _pinyin = "";public string CityName{get { return _cityName; }set{_cityName = value;OnNotifyPropertyChanged("CityName");}}public string Pinyin{get { return _pinyin; }set { _pinyin = value; }}}
Model類很簡單,就2個屬性,CityName為中文名稱,Pinyin(嗯,確實是拼音……)為城市的拼音名。
為了實現中Items的顯示效果,我們需要對其模版進行修改,具體XAML如下:
<phone:PhoneApplicationPage.Resources><DataTemplate x:Key="AutoItemTemplate"><Grid Width="400" Height="50"><TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding CityName}" d:LayoutOverrides="Height"/><TextBlock HorizontalAlignment="Left" Margin="200,0,57,8" TextWrapping="Wrap" Text="{Binding Pinyin}" d:LayoutOverrides="Height"/></Grid></DataTemplate></phone:PhoneApplicationPage.Resources><toolkit:AutoCompleteBox x:Name="TxtUserInput" Margin="0,8,0,0" ItemTemplate="{StaticResource AutoItemTemplate}" ValueMemberPath="CityName" Height="73" VerticalAlignment="Top" />
上面的XAML代碼中唯一需要說明的就是AutoCompleteBox的ValueMemberPath屬性,由於Item的資料來源是CityModel類型的,如,這時如果使用者點擊“北京 beijing”這個項目時,在文字框中是顯示"北京"或者"beijing"就取決於ValueMemberPath的設定了。
在XAML的CS頁面裡,需要進一步指定AutoCompleteBox的資料來源(抱歉沒有嚴格使用MVVM綁定,這不是重點。。)
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e){viewModel = new InputCityNameViewModel();this.DataContext = viewModel;TxtUserInput.ItemsSource = viewModel.ListCities;TxtUserInput.FilterMode = AutoCompleteFilterMode.Custom;TxtUserInput.ItemFilter = viewModel.Filter;TxtUserInput.Focus();}
ViewModel裡的一些內容:
public class InputCityNameViewModel : BaseViewModel{public IList<CityModel> ListCities = new List<CityModel>();public InputCityNameViewModel(){LoadCities();}private void LoadCities(){//讀取城市資訊}public bool Filter(string strInput, object toFilter){CityModel model = (CityModel)toFilter;if (model.Pinyin.StartsWith(strInput) || model.CityName.StartsWith(strInput))return true;else{return false;}}}
這裡的關鍵就是Filter了,代碼很簡單,很容易看懂。
順便再談一個Bug的問題,AutoCompleteBox在Pivot裡面的提示顯示是不正常的,而且顯示和觸控是錯位的,網上有大牛給出了變相的解決辦法,但我一直認為那太複雜,個人比較懶。。前兩天Bing了一下,突然眼前一亮,紀念一下:
粗略看了摘要之後(確實是粗略,因為中間有”…”我也沒太注意),我當時以為隨著Toolkit的新版的發布,這個問題已經解決了,但是點擊進去一看,發現“Toolkit新版發布”和“AutoCompleteBox在Pivot的Bug的解決”這完全是兩篇不同的文章…… 徹底崩潰。。
但是必須要在Pivot裡面讓使用者輸入城市名字的,這個怎麼辦。後來直接用了個笨點的辦法,我把Pivot裡面的AutoCompleteBox換成了TextBox,然後當Text獲得焦點之後,跳轉到一個新頁面,空白頁面上只有AutoCompleteBox,當使用者輸入完成之後再把值傳遞迴去,算是個障眼法麼。。不過我記得有很多時候在手機上都是這麼做的——當使用者點擊輸入框之後螢幕上只顯示輸入框和鍵盤及候選字,輸入完之後再返回去。這樣使用者體驗也不會太差,總比在Pivot上面硬生生的讓使用者直面Bug來得好,這也算是一個臨時的解決辦法吧,期待Toolkit的升級~