【www.bbyears.com--Windows7】
AutoSuggestBox控件与TextBox控件相似,但,AutoSuggestBox控件可以提供一个下拉列表,用户可以从弹出的下拉列表中选择一个项,并把被选项的内容显示在输入框上。就类似于搜索引擎的输入页面。
在使用AutoSuggestBox控件时,要注意它有几个重要事件。
a、当下拉列表中的项被选择后,会发生SuggestionChosen事件。
b、当在QuerySubmitted的下拉列表中做出选择后,或者单击输入框右边的查找图标(如果有,需自行设置)会提交输入的文本,这时候会发生QuerySubmitted事件,从事件参数的QueryText属性可以获得输入框中要提交的查询文本。
当输入框中的文本发生变化后,会发生TextChanged事件,但是要注意,这个事件比较危险,很容易引发死循环。如果你在处理该事件时修改了控件的Text属性,那么又会再次引发该事件;如果再次引发时又对Text属性进行修改,那么,TextChanged事件就会再引发……这样就很容易进入无限循环。
下面看个例子,XAML如下:
QuerySubmitted="ab1_QuerySubmitted"
SuggestionChosen="ab1_SuggestionChosen"/>
QueryIcon属性指定一个图标,这个图标显示在输入框的右侧。我这里用的“查找”图标。
以下代码处理上述事件:
private void ab1_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
tbmsgForAb1.Text = $"你要查询的内空:{args.QueryText}。";
}
private void ab1_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
string s = args.SelectedItem as string;
// 将从下拉列表中选择的项放入输入框
sender.Text += s ?? string.Empty;
}
那么,如何为AutoSuggestBox控件设置下拉列表呢。
其实AutoSuggestBox控件是从ItemsControl派生出来的,所以你懂的,就把它当成普通的列表控件对待就行了,既可以手动添加子项,也可以用ItemsSource属性来指定数据源。
比如这样:
string[] arrsrc = new string[]
{
"as", "at","above","cat","come","flag","girl","good","tool","too","look","book","socket","yellow","you","window","wave"
};
……
ab1.ItemsSource = arrsrc;
来,看看结果。
AutoSuggestBox类还公开了一个名为TextMemberPath的属性,这个属性又有啥用呢。
刚才说过,AutoSuggestBox控件是从ItemsControl类派生出来的,也就是说,放进AutoSuggestBox的下拉列表中的项不一定是字符串,很有可能是复杂类型的实例,但,文本框中要显示的内容必须是字符串。所以,有了TextMemberPath属性,就可以指定一个属性的名字,这个值就是要从数据源对象的某个属性中去取值。
举个例子,比如我定义一个类,用来封装一家快递公司的信息。ExpName属性表示快递公司的名字,PhoneNo属性表示快递公司的电话,ExpIcon表示快递公司的Logo图标。于是就有了这个类定义:
public class ExpInfo
{
public string ExpName { get; set; }
public string PhoneNo { get; set; }
public ImageSource ExpIcon { get; set; }
}
然后,用XAML声明一个AutoSuggestBox实例。
QuerySubmitted="ab2_QuerySubmitted"
TextMemberPath="ExpName">
因为下拉列表中要显示的是复杂对象,所以自定义一下ItemTemplate的布局。TextMemberPath="ExpName"表明,当用户从弹出的下拉列表中选择一个项后,AutoSuggestBox控件会从被选项(实为ExpInfo实例)对象的ExpName属性上获取字符串对象,然后显示在AutoSuggestBox控件的输入框上。
当程序运行后,就能看到以下效果。
OK,AutoSuggestBox控件的事,就介绍完了。哦,还有,UWP平台其实还沿用了8.1中的一个叫SearchBox的控件,功能也和AutoSuggestBox差不多。
UWP新控件AutoSuggestBox介绍
要开发一款优秀的application,控件肯定是必不可少的,uwp就为开发者提供了各种各样的系统控件,AutoSuggestBox就是uwp极具特色的控件之一,也是相对于之前win8.1的uap较新的控件,今天我们就来谈谈AutoSuggestBox的基本用法及其自定义UI方法。
A Simplest Sample
话不多说,先来个小Demo。
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AutoSuggestBoxSample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
PlaceholderText="Type a control name"
TextChanged="AutoSuggestBox_TextChanged"
QueryIcon="Find"
QuerySubmitted="AutoSuggestBox_QuerySubmitted"
Width="300"
HorizontalAlignment="Center"/>
//MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace AutoSuggestBoxSample
{
///
/// An empty page that can be used on its own or navigated to within a Frame.
///
public sealed partial class MainPage : Page
{
public MainPage()
{
suggestions = new ObservableCollection
this.InitializeComponent();
}
private ObservableCollection
private void AutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
if (args.ChosenSuggestion != null)
textBlock.Text = args.ChosenSuggestion.ToString();
else
textBlock.Text = sender.Text;
}
private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
suggestions.Clear();
suggestions.Add(sender.Text + "1");
suggestions.Add(sender.Text + "2");
sender.ItemsSource = suggestions;
}
}
}
运行结果如图所示:
Understand the code above
上面的代码定义了一个最简单的AutoSuggestBox,先看xaml部分,在AutoSuggestBox标签部分,定义了PlaceHolderText,就是在没有输入的时候显示的Hint。QueryIcon是控件最右边的搜索按钮,等号右边的Find是系统自带的icon,当然也可以选择其它icon,后面我们会说,这个属性可以不设置,这样的话,AutoSuggestBox则不会显示最右边的搜索按钮。而TextChanged和QuerySubmitted对应的是两个事件,事件的定义在MainPage.xaml.cs里面。这里注意一下,除了这两个事件外,还有一个会经常用到并且容易理解错误的事件SuggestionChosen,每次在List选择之后,会自动触发这个事件,除此之外,QuerySubmitted也会触发一次,所以在使用过程中,搞清楚两者之间的关系是必要的。
What if the data set is something else?
细心的读者可能会发现,在上面的例子中,我们仅仅是显示了一个字符串列表,可是在实际开发中,谁又能保证suggestions只能是字符串呢?这当然是不可能的。幸运的是,AutoSuggestBox的Suggestion List其实就是一个ListView,我们可以通过定义ItemTemplate来使ListViewItem展示不同的数据,对AutoSuggestBox来说,当然也是可行的。举例来说,当数据集为SampleSuggest对象:
public class SampleSuggest
{
public int Index { set; get; }
public String Value { set; get; }
}
若要正常显示ListViewItem,则需要在XAML里面定义AutoSuggestBox的ItemTemplate属性,如下所示:
PlaceholderText="Type a control name"
TextChanged="AutoSuggestBox_TextChanged"
QueryIcon="Find"
QuerySubmitted="AutoSuggestBox_QuerySubmitted"
Width="300"
HorizontalAlignment="Center">
这样ListViewItem就能按照我们的定义显示了:
但是,当我们点击列表时,TextBox里面显示的却是AutoSuggestBoxSample.SampleSuggest,这显然不是我们想要的。因为在选择ListViewItem的时候,系统会自动调用选中数据的ToString()方法,将得到的字符串显示在TextBox中。为了放着这种情况发生,我们可以选择重写SampleSuggest的ToString()方法,或者为AutoSuggestBox添加 SuggestionChosen事件,在事件中根据Suggestion决定TextBox中显示的内容,在这里,文章将使用第二种方法。
首先,在AutuSuggestBox的XAML定义中,添加以下属性:
SuggestionChosen="AutoSuggestBox_SuggestionChosen"
然后,在相应的cs文件中添加如下代码:
private void AutoSuggestBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
SampleSuggest suggest = args.SelectedItem as SampleSuggest;
if (suggest == null)
return;
sender.Text = suggest.Value;
}
这样,一个AutoSuggestBox的功能就基本完成了!!
[Ignorable]
A story which is not interesting
这里,请允许小编插入一段不是很有趣的故事……不喜欢的读者可以直接跳过……
小编接到任务,需要开发一个这样的控件:
小编看到,立刻就开心了,这不是AutoSuggestBox嘛!!简单!!
于是,小编很兴奋地写下了以下代码:
PlaceholderText="anything to search?"
BorderThickness="0"
Background="#232323"
Foreground="White"
QueryIcon="Find"
VerticalContentAlignment="Center"
Width="500"
Height="50"
HorizontalAlignment="Center"/>
结果出来的结果是这个样子的……
此时,小编的心情是这样的……
于是乎,小编便下定决心要改改这个AutoSuggestBox,就有了下边的内容……
Style the AutoSuggestBox
通过以上的程序,我们实现了AutoSuggestBox的基本功能,但是这样一个控件一般都不会满足我们程序开发的需求,因为它长得似乎不那么漂亮,或者说,不那么满足我们的需求。所以,我们要自己定义AutoSuggestBox的style,让它看上去更有范儿!
在VS designer的Document Outline面板中右键点击定义的AutoSuggestBox -> Edit Template -> Edit a Copy…,则会在XAML里生成AutoSuggestBox的Style。
通过观察以下由VS生成的Style代码,我们可以知道,这个神奇的AutoSuggestBox其实就是由一个TextBox和一个Popup构成的:
那么AutoSuggestBox的外观,基本就是由其中的TextBox决定的,其中对应的就是一个AutoSuggestBoxTextBoxStyle:
有了这个,我们就可以轻松定义AutoSuggestBox的外观啦!我们再看这个AutoSuggestBoxTextBoxStyle,它主要由以下几个部分构成:ContentElement,它是一个ScrollViewer,就是我们TextBox中的输入部分;PlacehoderTextContentPresenter,通过它的名字,我们可以知道它就是显示PlacehoderText的部分;还有DeleteButton和QueryButton两个按钮,分别对应控件中的删除按钮和查询按钮:
这下就清楚很多了,那么我们就开始改造我们的AutoSuggestBox吧!
首先是Foreground和Background,将AutoSuggestBoxTextBoxStyle里以下代码替换为:
然后,去掉Border:
改变DeleteButton的VisualState,主要是PointOver和Pressed两种状态:
接着去Style我们的QueryButton,首先是QueryIcon:
PlaceholderText="anything to search?"
BorderThickness="0"
Background="#232323"
Foreground="White"
VerticalContentAlignment="Center"
Width="500"
Height="50"
HorizontalAlignment="Center" Style="{StaticResource AutoSuggestBoxStyle1}">
然后是Button的大小,从Style里面去更改:
修改QueryButton的Background,注意这里并不能直接在Button里添加Background属性,而是在QueryButtonStyle里的ContentPresenter里面修改,同时把Margin设置为0,以便于能填充全部背景:
因为调整了QueryButton的高度,所以控件整体高度会变高,为了让TextBox里面的Text能够垂直居中,需要在AutoSuggestBoxTextBoxStyle中,将显示正文的ContentElement和显示hint的PlaceholderTextContentPresenter的VerticalAlignment设为Center,同时设置FontSize:
程序运行结果如下图所示:
和目标发现,好像还有什么不一样的……对!是Background!可是我们已经设置过Background啦……这是为什么呢?通过观察Style,我们发现,有许多VisualState的Background都有Transparent的属性,也就是说,AutoSuggestBox显示出来的Background和它的父控件式相关的。简单起见,我们直接为AutoSuggestBox添加一个背景色相同的Grid就好:
PlaceholderText="anything to search?"
Style="{StaticResource AutoSuggestBoxStyle1}">
再执行程序,发现和目标就相同了!!
Consulting
本文概括地介绍了AutoSuggestBox的使用方法以及简单自定义Style,希望初次使用该控件的开发者能够从中得到些许帮助并交流一些开发经验,谢谢!