WPF自定义搜索控件

在利用WPF开发桌面软件时,我们常常会用到自动搜索功能:在一个搜索框中输入搜索关键字,得到搜索结果,并可以选择某一项搜索结果。WPF中没有这样的预定义控件,不过这一搜索功能可以简单的利用TextBox来实现,我们只需要监听TextBox的TextChanged事件,在事件处理方法中查找搜索源中与输入关键字匹配的项。但是,如果这样的搜索场景被大量使用的时候,最好的处理方式是封装一个可专门用于搜索功能
摘要由CSDN通过智能技术生成


       原文链接:http://blog.csdn.net/zhuo_wp/article/details/78821711    转载请注明出处


       在利用WPF开发桌面软件时,我们常常会用到自动搜索功能:在一个搜索框中输入搜索关键字,得到搜索结果,并可以选择某一项搜索结果。WPF中没有这样的预定义控件,不过这一搜索功能可以简单的利用TextBox来实现,我们只需要监听TextBox的TextChanged事件,在事件处理方法中查找搜索源中与输入关键字匹配的项。但是,如果这样的搜索场景被大量使用的时候,最好的处理方式是封装一个可专门用于搜索功能的自定义控件。本文即是简要的说明其思路与简单实现的。


       一 设计思路

       

       如图所示,从界面上说,搜索控件主要有三个部分:

       1 搜索关键字输入部分,主要用于搜索关键字的输入,可以用WPF中的TextBox来实现,需要监听TextBox的TextChanged事件。

        2 清除搜索关键字按钮,用于一键清除输入框中的关键字,可用Button来实现。

        3 搜索结果展示部分,用于展示搜索结果,并且只有在有搜索结果的时候才展示,可以用WPF中的Popup来实现。

       此外,还可以显示搜索提示语和搜索图标。

       在应用控件的时候,搜索数据源是可以从控件外部提供的,所以需要依赖属性来绑定搜索源,同时搜索提示语可以通过依赖属性来提供自定义设置功能。


       二 代码结构

       如图所示,整个控件的代码结构包括用于界面构建的SearchableTextBox.xaml文件,用于搜索逻辑控制的SearchableTextBox.cs文件,用于将原始数据构造成可搜索数据的SearchModel类,以及一些辅助方法类。

       


       三 模板代码

       如下所示,搜索控件的默认模板包括:

       1 一个Path元素,用于显示搜索图标。

       2 一个TextBlock控件,用于显示搜索提示语。

       3 一个TextBox控件, 用于数据搜索关键字。

       4 一个Button控件,用于一键清除输入框中的内容。

       5 一个Popup和一个ListBox,用于显示搜索结果。

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SearchableTextBox"
    xmlns:cvt="clr-namespace:SearchableTextBox.Converters">
    
    <cvt:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
    <cvt:CornerRadiusToDoubleConverter x:Key="CornerRadiusToDoubleConverter"/>

    <Style TargetType="{x:Type local:SearchableTextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:SearchableTextBox}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}" 
                            CornerRadius="{TemplateBinding  CornerRadius}"
                            Background="{TemplateBinding Background}"
                            Padding="{TemplateBinding Padding}">
                        <Grid x:Name="PART_Root">

                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto"/>
                                <ColumnDefinition Width="auto"/>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="auto" />
                                <ColumnDefinition Width="auto"/>
                            </Grid.ColumnDefinitions>

                            <Grid Grid.Column="0" Width="{TemplateBinding CornerRadius, Converter={StaticResource CornerRadiusToDoubleConverter}}"/>

                            <Path Grid.Column="1" Width="{TemplateBinding SearchIconWidth}"
                                  Height="{TemplateBinding SearchIconHeight}" 
                                  Visibility="{TemplateBinding IsShowSearchIcon, Converter={StaticResource BoolToVisibilityConverter}}" 
                                  Stretch="Fill" Fill="{TemplateBinding SearchIconForeground}"
                                  Data="{TemplateBinding SearchIcon}">
                            </Path>

                            <TextBlock x:Name="PART_TextBlockTips" Grid.Column="2" Text="{TemplateBinding SearchTips}" Margin="15,0,0,0"
                                       Foreground="{TemplateBinding SearchTipsForeground}"
                                       HorizontalAlignment="Left" VerticalAlignment="Center"/>

                            <TextBox x:Name="PART_TextBoxInput" Grid.Column="2" 
                                     Text="{Binding SearchText,Delay=500, Mode=TwoWay,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:SearchableTextBox}, UpdateSourceTrigger=PropertyChanged}"
                                     BorderBrush="Transparent" BorderThickness="0" Background="Transparent"
                                     HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                                     HorizontalContentAlignment="Left" VerticalContentAlignment="Center"/>

                            <Button x:Name="PART_ButtonClear" Grid.Column="3" Visibility="Collapsed">
                                <Button.Template>
                                    <ControlTemplate>
                                        <Grid>
                                            <Label Content="x"/>
                                        </Grid>
                                    </ControlTemplate>
                                </Button.Template>
                            </Button>

                            <Grid Grid.Column="4" Width="{TemplateBinding CornerRadius, Converter={StaticResource CornerRadiusToDoubleConverter}}"/>

                            <Popup x:Name="PART_Popup"
                                   AllowsTransparency="true"
                                   PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"
                                   Placement="Bottom"
                                   StaysOpen="False">
                                <Border Padding="0,0,4,0">
                                    <Border x:Name="Shdw"
                                            Background="Transparent"
                                            MaxWidth="252"
                                            MinWidth="{Binding ActualWidth, ElementName=PART_Root}">
                                        <Border x:Name="DropDownBorder"
                                                Margin="0,4,0,0"
                                                BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}"
                                                BorderThickness="1"
                                                Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
                                            <Grid RenderOptions.ClearTypeHint="Enabled">
                                                <Border Padding="14"
                                                        Background="White"
                                                        Name="NoResultBorder">
                                                    <TextBlock Text="无匹配结果"
                                                               Foreground="Black" />
                                                </Border>
                                                <ListBox x:Name="PART_ListBoxSearchResult"
                                                         ItemsSource="{TemplateBinding SearchResultCollection}"
                                                         Foreground="Black"
                                                         Margin="0,10"
                                                         Padding="0"
                                                         Background="White"
  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值