WPF自定义搜索框控件样式

效果图
默认
image
焦点触发
image

新建一个用户控件,xaml代码如下:
`

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="15"></ColumnDefinition>
        <ColumnDefinition Width="*"></ColumnDefinition>
        <ColumnDefinition Width="36"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Rectangle Grid.Column="0" Grid.ColumnSpan="3" Stroke="White" Fill="Transparent" Height="35" RadiusX="10" RadiusY="10" Opacity="0.8"></Rectangle>
    <TextBox x:Name="TbxInput"  Grid.Column="1"  Background="Transparent" Height="35" KeyDown="TbxInput_OnKeyDown" >
        <TextBox.Template>
            <ControlTemplate TargetType="TextBox">
                <Grid>
                    <TextBlock x:Name="Uc_TblShow" Text="{Binding ElementName=MyControl,Path=PreviewTxt}"  Foreground="White" Opacity="0.5" VerticalAlignment="Center" Visibility="Collapsed"></TextBlock>
                    <TextBox x:Name="Uc_TbxContent" Width="250" Style="{StaticResource NormalTextBox}" Foreground="White" Background="Transparent"  VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0"
                             Text="{Binding ElementName=TbxInput,Path=Text,Mode=TwoWay}" FontSize="18"></TextBox>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger SourceName="Uc_TbxContent" Property="Text" Value="">
                        <Setter TargetName="Uc_TblShow" Property="Visibility" Value="Visible"></Setter>
                    </Trigger>
                    <Trigger SourceName="Uc_TbxContent" Property="IsFocused" Value="True">
                        <Setter TargetName="Uc_TblShow" Property="Visibility" Value="Collapsed"></Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </TextBox.Template>
    </TextBox>
    <Button x:Name="BtnSearch" Grid.Column="2" Click="BtnSearch_OnClick" Cursor="Hand">
        <Button.Template>
            <ControlTemplate TargetType="Button">
                <Grid>
                    <Label x:Name="Uc_Image" Style="{StaticResource NormalLabel}" VerticalContentAlignment="Center" Content="&#xf002;" Height="35" Width="35"></Label>
                    <ContentPresenter></ContentPresenter>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter TargetName="Uc_Image" Property="Height" Value="25"></Setter>
                        <Setter TargetName="Uc_Image" Property="Width" Value="25"></Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Button.Template>
    </Button>
</Grid>`

后台代码:
`

public partial class SearchTextBox : UserControl
{
    public SearchTextBox()
    {
        InitializeComponent();
     
    }
    public ICommand BtnCommand
    {
        get { return (ICommand)GetValue(BtnCommandProperty); }
        set { SetValue(BtnCommandProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Command.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty BtnCommandProperty =
        DependencyProperty.Register("BtnCommand", typeof(ICommand), typeof(SearchTextBox), new PropertyMetadata(default));



    public object CommandParameter
    {
        get { return (object)GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }

    // Using a DependencyProperty as the backing store for CommandParameter.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(SearchTextBox), new PropertyMetadata(default));



    public string PreviewTxt
    {
        get { return (string)GetValue(PreviewTxtProperty); }
        set { SetValue(PreviewTxtProperty, value); }
    }

    // Using a DependencyProperty as the backing store for PreviewTxt.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PreviewTxtProperty =
        DependencyProperty.Register("PreviewTxt", typeof(string), typeof(SearchTextBox), new PropertyMetadata("输入"));

   
    public event EventHandler<SearchEventArgs> OnSearch;
    private void BtnSearch_OnClick(object sender, RoutedEventArgs e)
    {
        if (this.BtnCommand != null)
        {
            this.BtnCommand.Execute(TbxInput.Text);
        }
        ExeccuteSearch();
    }

    private void TbxInput_OnKeyDown(object sender, KeyEventArgs e)
    {
        ExeccuteSearch();
    }

    private void ExeccuteSearch()
    {
        if (OnSearch != null)
        {
            var args = new SearchEventArgs();
            args.SearchText = TbxInput.Text;
            OnSearch(this, args);
        }
    }
}
public class SearchEventArgs : EventArgs
{
    public string SearchText { get; set; }
}`

其中

  • PreviewTxt属性用来设置搜索框的默认提示文字,类似PlaceHolder属性。
  • BtnCommand用来对外绑定ViewModel中的Command,点击按钮触发Click事件时执行Command

默认将输入的搜索内容作为Command命令参数,因此外部调用控件时,不需要再传递参数。

画面中调用控件方式如下:
<controls:SearchTextBox DockPanel.Dock="Right" Width="300" PreviewTxt="输入接口名称/描述" Command="{Binding XXXCommand}" Margin="0 0 10 0" ></controls:SearchTextBox>

posted @ 2022-12-18 11:41  cyberneo666  阅读(528)  评论(1编辑  收藏  举报