自定义搜索框,
需要以下基础知识
:
- XAML编写,可以直接从Blend粘贴微软的模板,再对模板进行改写
- 依赖属性与附加属性,自定义依赖属性Vs下propdp再按两下Tab就自动创建好模板了
- 自定义路由事件,自定义路由事件:1.声明注册路由事件2.添加CRL事件包装器3.触发路由事件
- Binding的方法(C#中),搜索框的属性需要与TextBox的Text进行绑定,方便用户的调用,此外几种绑定都要掌握
- 控件模板,本搜索框(ContentControl)由TextBox+Button组合而成
- 控件库的创建,引用dll控件库,
文章目录
XAML对搜索框进行编写
- SearchBox分为TextBox与Button两部分
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:yang="clr-namespace:YangControlLibrary.Themes"> <!--搜索按钮--> <Style x:Key="SearchInputBoxSearchButton" TargetType="Button"> <Setter Property="Background" Value="Transparent"/> <Setter Property="BorderBrush" Value="Transparent"/> <Setter Property="Height" Value="26"/> <Setter Property="Width" Value="26"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Border x:Name="border" BorderBrush="Transparent" BorderThickness="0" Background="Transparent" SnapsToDevicePixels="true"> <Path x:Name="SearchPath" Stroke="#2561a9" StrokeThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center"> <Path.Data> <GeometryGroup> <EllipseGeometry RadiusX="7.5" RadiusY="7.5" Center="10,10" /> <LineGeometry StartPoint="0,20" EndPoint="5,15"/> </GeometryGroup> </Path.Data> </Path> </Border> <ControlTemplate.Triggers> <Trigger Property="IsDefaulted" Value="true"> <Setter Property="BorderBrush" TargetName="border" Value="Transparent"/> </Trigger> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Background" TargetName="border" Value="#b4b4b4"/> <Setter Property="BorderBrush" TargetName="border" Value="Transparent"/> </Trigger> <Trigger Property="IsPressed" Value="true"> <Setter Property="Background" TargetName="border" Value="Blue"/> <Setter Property="BorderBrush" TargetName="border" Value="Transparent"/> <Setter Property="Stroke" TargetName="SearchPath" Value="White"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Background" TargetName="border" Value="Transparent"/> <Setter Property="BorderBrush" TargetName="border" Value="Transparent"/> <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="Transparent"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <!--搜索文本框--> <Style x:Key="InputTextBox" TargetType="{x:Type TextBox}"> <Setter Property="Height" Value="30"/> <Setter Property="Width" Value="150"/> <Setter Property="FontSize" Value="14px"/> <Setter Property="Background" Value="White"/> <Setter Property="BorderBrush" Value="Wheat"/> <Setter Property="BorderThickness" Value="2"/> <Setter Property="Foreground" Value="#ac4da8"/> <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/> <Setter Property="HorizontalContentAlignment" Value="Left"/> <Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="AllowDrop" Value="true"/> <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/> <Setter Property="Stylus.IsFlicksEnabled" Value="False"/> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="MaxLength" Value="8"/> <!--文本框选择器--> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TextBox}"> <Border x:Name="border" BorderBrush="White" BorderThickness="2" Background="#b4b4b4" SnapsToDevicePixels="True"> <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Opacity" TargetName="border" Value="0.56"/> </Trigger> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="BorderBrush" TargetName="border" Value="Blue"/> </Trigger> <Trigger Property="IsKeyboardFocused" Value="true"> <Setter Property="BorderBrush" TargetName="border" Value="Blue"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style TargetType="{x:Type yang:SearchBox}"> <Setter Property="Height" Value="30"/> <Setter Property="Width" Value="150"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type yang:SearchBox}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="4*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBox x:Name="InputTextBox" Text="{TemplateBinding SearchContent}" Style="{StaticResource InputTextBox}" Grid.Column="0" Grid.ColumnSpan="2"/> <Button x:Name="SearchInputBoxSearchButton" Style="{StaticResource SearchInputBoxSearchButton}" Grid.Column="1"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
UI控件逻辑
自定义事件,当Button的Click事件发生时触发自定义事件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace YangControlLibrary.Control
{
[TemplatePart(Name = "InputTextBox", Type = typeof(TextBox))]
[TemplatePart(Name = "SearchInputBoxSearchButton", Type = typeof(Button))]
public class SearchBox : ContentControl
{
private TextBox textbox;
public string SearchContent
{
get { return (string)GetValue(SearchContentProperty); }
set { SetValue(SearchContentProperty, value); }
}
// 添加依赖属性
public static readonly DependencyProperty SearchContentProperty =
DependencyProperty.Register("SearchContent", typeof(string), typeof(SearchBox), new PropertyMetadata(string.Empty));
//点击按钮SearchButton更新SearchContent,
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var butSearch = base.GetTemplateChild("SearchInputBoxSearchButton") as Button;
textbox = base.GetTemplateChild("InputTextBox") as TextBox;
if (textbox != null)
{
var binding = new Binding("SearchContent")
{
Source = this,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
textbox.SetBinding(TextBox.TextProperty, binding);
}
if (butSearch != null)
{
butSearch.Click += new RoutedEventHandler(Button_Click);
}
}
private void SearchBox_ClickSearchButton(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}
private void Button_Click(object sendeer, RoutedEventArgs e)
{
if (textbox != null)
{
RaiseEvent(new FunctionEventArgs<string>(SearchEvent, this)
{
Info = SearchContent
});
}
}
//自定义ClickSearchButton事件
//声明并注册路由事件
public static readonly RoutedEvent SearchEvent =
EventManager.RegisterRoutedEvent("Search",
RoutingStrategy.Bubble, typeof(EventHandler<FunctionEventArgs<string>>), typeof(SearchBox));
//为路由事件添加CLR事件包装器
public event EventHandler<FunctionEventArgs<string>> Search
{
add { this.AddHandler(SearchEvent, value); }
remove { this.RemoveHandler(SearchEvent, value); }
}
}
}