WPF 搜索框控件样式
完全通过Xaml代码实现,使用了UserControl进行封装。功能包括聚焦时控件展开,输入为空时的文字提示,以及待选提示项列表等效果。实现效果如下图:
xaml代码
<UserControl x:Class="SearchBar.SearchBox"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:SearchBar"UseLayoutRounding="True"TextElement.FontSize="14"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="440"><UserControl.Resources><SolidColorBrush x:Key="Control.BoderBrush" Color="#CBCBCB"/><Style TargetType="{x:Type TextBox}"><Setter Property="Background" Value="#FFF2F3F4"/><Setter Property="BorderBrush" Value="{StaticResource Control.BoderBrush}"/><Setter Property="Foreground" Value="#515151"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="Padding" Value="8 0 0 0"/><Setter Property="BorderThickness" Value="1"/><Setter Property="KeyboardNavigation.TabNavigation" Value="None"/><Setter Property="HorizontalContentAlignment" Value="Left"/><Setter Property="AllowDrop" Value="true"/><Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/><Setter Property="Stylus.IsFlicksEnabled" Value="False"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type TextBox}"><Border x:Name="border" CornerRadius="8" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True"><Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition Width="44"/></Grid.ColumnDefinitions><Border x:Name="bdLeft" CornerRadius="8" Margin="4 4 8 4"><Grid><ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/><TextBlock Text="输入搜索内容" VerticalAlignment="Center" Margin="10 0" Opacity="0.8"><TextBlock.Style><Style TargetType="TextBlock"><Setter Property="Visibility" Value="Collapsed" /><Style.Triggers><DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=TextBox},Path=Text}" Value=""><Setter Property="Visibility" Value="Visible"/></DataTrigger></Style.Triggers></Style></TextBlock.Style></TextBlock></Grid></Border><Button Grid.Column="1" Margin="4"><Button.Style><Style TargetType="Button"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Button"><Border x:Name="bd" CornerRadius="8" Background="Transparent"><ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"></ContentPresenter></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="bd" Property="Background" Value="#60CACACA"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style></Button.Style><Path Fill="#C9000000" Margin="8" Stretch="Uniform" Data="M15.7 13.3l-3.81-3.83A5.93 5.93 0 0013 6c0-3.31-2.69-6-6-6S1 2.69 1 6s2.69 6 6 6c1.3 0 2.48-.41 3.47-1.11l3.83 3.81c.19.2.45.3.7.3.25 0 .52-.09.7-.3a.996.996 0 000-1.41v.01zM7 10.7c-2.59 0-4.7-2.11-4.7-4.7 0-2.59 2.11-4.7 4.7-4.7 2.59 0 4.7 2.11 4.7 4.7 0 2.59-2.11 4.7-4.7 4.7z"></Path></Button></Grid></Border><ControlTemplate.Triggers><Trigger Property="IsEnabled" Value="false"><Setter Property="Opacity" TargetName="border" Value="0.56"/></Trigger><Trigger Property="IsMouseOver" Value="true"><Setter Property="Background" TargetName="border" Value="white"/></Trigger><Trigger Property="IsKeyboardFocused" Value="true"><Setter Property="Background" TargetName="bdLeft" Value="#60CACACA"/><Setter Property="BorderBrush" TargetName="border" Value="Transparent"/><Setter Property="Background" TargetName="border" Value="white"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter><Style.Triggers><MultiTrigger><MultiTrigger.Conditions><Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/><Condition Property="IsSelectionActive" Value="false"/></MultiTrigger.Conditions><Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/></MultiTrigger></Style.Triggers></Style></UserControl.Resources><Grid><Grid.RowDefinitions><RowDefinition Height="44"/><RowDefinition Height="auto"/></Grid.RowDefinitions><Border Grid.RowSpan="2" BorderThickness="1" Background="White" BorderBrush="{StaticResource Control.BoderBrush}" CornerRadius="8"><Border.Effect><DropShadowEffect Color="Gray" Opacity="0.2" ShadowDepth="0" BlurRadius="12"/></Border.Effect><Border.Style><Style TargetType="Border"><Setter Property="Visibility" Value="Collapsed"/><Style.Triggers><DataTrigger Binding="{Binding ElementName=txtBox,Path=IsKeyboardFocused}" Value="True"><Setter Property="Visibility" Value="Visible"/></DataTrigger></Style.Triggers></Style></Border.Style><Grid Margin="0 44 0 12"><ListBox BorderBrush="Transparent" Padding="4 0"ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:SearchBox},Path=SearchList}"><ListBox.ItemContainerStyle><Style TargetType="ListBoxItem"><Setter Property="Padding" Value="8" /><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type ListBoxItem}"><Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"><ContentPresenter Opacity="0.8" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" x:Name="contentPresenter"/></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Background" Value="#20808080"/></Trigger><Trigger Property="IsSelected" Value="True"><Setter Property="Background" Value="#20808080"/></Trigger><MultiTrigger><MultiTrigger.Conditions><Condition Property="IsSelected" Value="true"/><Condition Property="Selector.IsSelectionActive" Value="false"/></MultiTrigger.Conditions><Setter Property="Background" TargetName="Bd" Value="#20808080"/></MultiTrigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style></ListBox.ItemContainerStyle></ListBox></Grid></Border><Grid><TextBox x:Name="txtBox"/></Grid><Grid Grid.Row="1" Height="280"></Grid></Grid>
</UserControl>
后台代码:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;namespace SearchBar
{/// <summary>/// SearchBox.xaml 的交互逻辑/// </summary>public partial class SearchBox : UserControl{public SearchBox(){InitializeComponent();}public ObservableCollection<string> SearchList{get { return (ObservableCollection<string>)GetValue(SearchListProperty); }set { SetValue(SearchListProperty, value); }}public static readonly DependencyProperty SearchListProperty =DependencyProperty.Register("SearchList", typeof(ObservableCollection<string>), typeof(SearchBox), new PropertyMetadata(new ObservableCollection<string>()));}
}
控件使用显示示例:
<Window x:Class="SearchBar.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:SearchBar"mc:Ignorable="d"Title="MainWindow" Height="500" Width="420"><Grid><Grid.RowDefinitions><RowDefinition Height="60"/><RowDefinition/></Grid.RowDefinitions><local:SearchBox x:Name="searchbox" Grid.RowSpan="2" Margin="8" Panel.ZIndex="50"></local:SearchBox><ListBox Grid.Row="1" Margin="16"><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem><ListBoxItem Padding="8">AAA</ListBoxItem></ListBox></Grid>
</Window>