WPF 自定义TextBox(WPF带图片,占位符,清除按钮的TextBox)改造版

效果:



Style:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ctrls="clr-namespace:ImageButtonTest01.Control"
    xmlns:converter="clr-namespace:ImageButtonTest01.Control.Converter">


    <converter:ImageTextBoxMarginLeftConverter x:Key="ITBMLC"/>
    <converter:PlaceholderFontSizeConverter x:Key="PHFSC"/>


    <SolidColorBrush x:Key="ImageTextBox.Static.BorderBrush" Color="#FF909090"/>
    <SolidColorBrush x:Key="ImageTextBox.Focused.BorderBrush" Color="#FF007ACC"/>
    <SolidColorBrush x:Key="ImageTextBox.MouseOver.BorderBrush" Color="#FF1E1E1E"/>


    <Style TargetType="{x:Type ctrls:ImageTextBox}">
        <Setter Property="Foreground" Value="Black"/>
        <Setter Property="Background" Value="White"/>
        <Setter Property="BorderBrush" Value="{StaticResource ImageTextBox.Focused.BorderBrush}"/>
        <Setter Property="BorderThickness" Value="2"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="CaretBrush" Value="Black"/>
        <Setter Property="Opacity" Value="1"/>
        <Setter Property="CornerRadius" Value="0"/>
        <Setter Property="FontSize" Value="18"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ctrls:ImageTextBox}">
                    <Border x:Name="border"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                            CornerRadius="{Binding CornerRadius, RelativeSource={RelativeSource TemplatedParent}}">


                        <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="{Binding CornerRadius.TopLeft, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ITBMLC}}"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>


                            <Image x:Name="PART_ContentIdentity" Grid.Column="1" Margin="0" Stretch="Uniform"
                                   Width="{Binding LeftImageWidth, RelativeSource={RelativeSource TemplatedParent}}"
                                   Height="{Binding LeftImageWidth, RelativeSource={RelativeSource TemplatedParent}}"
                                   Source="{Binding Image, RelativeSource={RelativeSource TemplatedParent}}"
                                   HorizontalAlignment="Center" VerticalAlignment="Center"/>


                            <ScrollViewer x:Name="PART_ContentHost" Grid.Column="2" IsTabStop="False" Margin="2,0,2,0"
                                          Focusable="false" Background="Transparent" SnapsToDevicePixels="True"
                                          HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"
                                          HorizontalAlignment="Stretch" VerticalAlignment="Center"
                                          FontSize="{Binding FontSize, RelativeSource={RelativeSource TemplatedParent}}"
                                          Foreground="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}"
                                          HorizontalContentAlignment="Left"/>


                            <TextBlock x:Name="PART_PlaceHolder" Grid.Column="2" IsHitTestVisible="False" Margin="3,0,3,0"
                                       HorizontalAlignment="Left" VerticalAlignment="Center"
                                       SnapsToDevicePixels="True"
                                       Visibility="Collapsed" Opacity="0.6"
                                       TextAlignment="{TemplateBinding TextAlignment}"
                                       Text="{Binding Path=PlaceHolder, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                       FontSize="{Binding FontSize, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource PHFSC}}"/>


                            <ctrls:ImageButton x:Name="PART_ClearTextButton" Grid.Column="3" Margin="2" IsTabStop="False"
                                               FontFamily="/ImageButtonTest01;component/Resources/#iconfont"
                                               Content="&#xe63c;" FontSize="20"
                                               HorizontalAlignment="Right"
                                               VerticalAlignment="Center"
                                               Style="{StaticResource ImageButtonTransparent}"/>


                            <ctrls:ImageButton x:Name="PART_ExtendIconFontButton" Grid.Column="4" FontSize="20"
                                               HorizontalAlignment="Center" VerticalAlignment="Center"
                                               FontFamily="/ImageButtonTest01;component/Resources/#iconfont"
                                               Content="{Binding ExtendIconFontText, RelativeSource={RelativeSource TemplatedParent}}"
                                               Style="{StaticResource ImageButtonTransparent}"
                                               Command="{Binding ExtendButtonCommand, RelativeSource={RelativeSource TemplatedParent}}"
                                               CommandParameter="{Binding ExtendButtonCommandParameter, RelativeSource={RelativeSource TemplatedParent}}"
                                               CommandTarget="{Binding ExtendButtonCommandTarget, RelativeSource={RelativeSource TemplatedParent}}"/>


                            <ctrls:ImageButton x:Name="PART_ExtendImageButton" Grid.Column="5"
                                               HorizontalAlignment="Center" VerticalAlignment="Center"
                                               FontFamily="/ImageButtonTest01;component/Resources/#iconfont"
                                               NormalImage="{Binding ExtendNormalImage, RelativeSource={RelativeSource TemplatedParent}}"
                                               HoverImage="{Binding ExtendHoverImage, RelativeSource={RelativeSource TemplatedParent}}"
                                               PressedImage="{Binding ExtendPressedImage, RelativeSource={RelativeSource TemplatedParent}}"
                                               DisabledImage="{Binding ExtendDisabledImage, RelativeSource={RelativeSource TemplatedParent}}"
                                               Style="{StaticResource ImageButtonTransparent}"
                                               Command="{Binding ExtendButtonCommand, RelativeSource={RelativeSource TemplatedParent}}"
                                               CommandParameter="{Binding ExtendButtonCommandParameter, RelativeSource={RelativeSource TemplatedParent}}"
                                               CommandTarget="{Binding ExtendButtonCommandTarget, RelativeSource={RelativeSource TemplatedParent}}"/>
                        </Grid>
                    </Border>


                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding Path=ExtendNormalImage, RelativeSource={RelativeSource Mode=Self}}" Value="{x:Null}">
                            <Setter TargetName="PART_ExtendImageButton" Property="Visibility" Value="Collapsed"/>
                        </DataTrigger>


                        <DataTrigger Binding="{Binding Path=ExtendIconFontText, RelativeSource={RelativeSource Mode=Self}}" Value="">
                            <Setter TargetName="PART_ExtendIconFontButton" Property="Visibility" Value="Collapsed"/>
                        </DataTrigger>


                        <DataTrigger Binding="{Binding Path=Text, RelativeSource={RelativeSource Mode=Self}}" Value="">
                            <Setter TargetName="PART_PlaceHolder" Property="Visibility" Value="Visible"/>
                            <Setter TargetName="PART_ClearTextButton" Property="IsEnabled" Value="False"/>
                            <Setter TargetName="PART_ExtendIconFontButton" Property="IsEnabled" Value="False"/>
                            <Setter TargetName="PART_ExtendImageButton" Property="IsEnabled" Value="False"/>
                        </DataTrigger>


                        <Trigger Property="IsFocused" Value="False">
                            <Setter TargetName="border" Property="BorderBrush" Value="{StaticResource ImageTextBox.Static.BorderBrush}"/>
                        </Trigger>


                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="border" Property="BorderBrush" Value="{StaticResource ImageTextBox.MouseOver.BorderBrush}"/>
                        </Trigger>


                        <Trigger Property="IsReadOnly" Value="True">
                            <Setter TargetName="PART_ClearTextButton" Property="IsEnabled" Value="False"/>
                            <Setter Property="Opacity" Value="0.6" TargetName="border" />
                        </Trigger>


                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Opacity" Value="0.5" TargetName="border" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

C#

ImageTextBox.CS

public class ImageTextBox : TextBox
{
    private ImageButton mClearTextButton = null;
    private ImageButton mExtendIconFontButton = null;
    private ImageButton mExtendImageButton = null;


    static ImageTextBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageTextBox), new FrameworkPropertyMetadata(typeof(ImageTextBox)));
    }


    public ImageTextBox()
    {
            
    }


    public override void OnApplyTemplate()
    {
        mClearTextButton = GetTemplateChild("PART_ClearTextButton") as ImageButton;
        if (null != mClearTextButton)
        {
            mClearTextButton.Click += OnClearTextClick;
        }


        mExtendIconFontButton = GetTemplateChild("PART_ExtendIconFontButton") as ImageButton;
        if (null != mExtendIconFontButton)
        {
            mExtendIconFontButton.Click += ExtendButtonClick;
        }


        mExtendImageButton = GetTemplateChild("PART_ExtendImageButton") as ImageButton;
        if (null != mExtendIconFontButton)
        {
            mExtendImageButton.Click += ExtendButtonClick;
        }


        base.OnApplyTemplate();
    }


    private void ExtendButtonClick(object sender, RoutedEventArgs e)
    {
        RoutedEventArgs re = new RoutedEventArgs(ImageTextBox.ExtendClickEvent, this);
        RaiseEvent(re);
    }


    private void OnClearTextClick(object sender, RoutedEventArgs e)
    {
        if (sender is ImageButton)
        {
            Text = "";
        }
    }


    public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(nameof(Image), typeof(ImageSource), typeof(ImageTextBox),
                                                                                            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, ImageSourceChanged));
    public ImageSource Image
    {
        get { return (ImageSource)GetValue(ImageProperty); }
        set { SetValue(ImageProperty, value); }
    }


    public static readonly DependencyProperty ExtendNormalImageProperty = DependencyProperty.Register(nameof(ExtendNormalImage), typeof(ImageSource), typeof(ImageTextBox),
                                                                                    new FrameworkPropertyMetadata(null));
    public ImageSource ExtendNormalImage
    {
        get { return (ImageSource)GetValue(ExtendNormalImageProperty); }
        set { SetValue(ExtendNormalImageProperty, value); }
    }


    public static readonly DependencyProperty ExtendHoverImageProperty = DependencyProperty.Register(nameof(ExtendHoverImage), typeof(ImageSource), typeof(ImageTextBox),
                                                                                    new FrameworkPropertyMetadata(null));
    public ImageSource ExtendHoverImage
    {
        get { return (ImageSource)GetValue(ExtendHoverImageProperty); }
        set { SetValue(ExtendHoverImageProperty, value); }
    }


    public static readonly DependencyProperty ExtendPressedImageProperty = DependencyProperty.Register(nameof(ExtendPressedImage), typeof(ImageSource), typeof(ImageTextBox),
                                                                                    new FrameworkPropertyMetadata(null));
    public ImageSource ExtendPressedImage
    {
        get { return (ImageSource)GetValue(ExtendPressedImageProperty); }
        set { SetValue(ExtendPressedImageProperty, value); }
    }


    public static readonly DependencyProperty ExtendDisabledImageProperty = DependencyProperty.Register(nameof(ExtendDisabledImage), typeof(ImageSource), typeof(ImageTextBox),
                                                                                    new FrameworkPropertyMetadata(null));
    public ImageSource ExtendDisabledImage
    {
        get { return (ImageSource)GetValue(ExtendDisabledImageProperty); }
        set { SetValue(ExtendDisabledImageProperty, value); }
    }


    public static readonly DependencyProperty PlaceHolderProperty = DependencyProperty.Register(nameof(PlaceHolder), typeof(string), 
                                                                typeof(ImageTextBox), new PropertyMetadata(""));
    public string PlaceHolder
    {
        get { return (string)GetValue(PlaceHolderProperty); }
        set { SetValue(PlaceHolderProperty, value); }
    }


    public static readonly DependencyProperty ExtendIconFontTextProperty = DependencyProperty.Register(nameof(ExtendIconFontText), typeof(string),
                                                                typeof(ImageTextBox), new PropertyMetadata(""));
    public string ExtendIconFontText
    {
        get { return (string)GetValue(ExtendIconFontTextProperty); }
        set { SetValue(ExtendIconFontTextProperty, value); }
    }


    public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register(nameof(CornerRadius), typeof(CornerRadius), 
        typeof(ImageTextBox), new PropertyMetadata(new CornerRadius(0,0,0,0)));
    public CornerRadius CornerRadius
    {
        get { return (CornerRadius)GetValue(CornerRadiusProperty); }
        set { SetValue(CornerRadiusProperty, value); }
    }


    public static readonly DependencyProperty LeftImageWidthProperty = DependencyProperty.Register(nameof(LeftImageWidth), typeof(double),
                                                                                    typeof(ImageTextBox), new PropertyMetadata(0.0));
    public double LeftImageWidth
    {
        get { return (double)GetValue(LeftImageWidthProperty); }
        set { SetValue(LeftImageWidthProperty, value); }
    }


    private static void ImageSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        ImageTextBox itb = sender as ImageTextBox;
        ImageSource image = e.NewValue as ImageSource;


        itb.SetValue(LeftImageWidthProperty, image.Width);
    }


    public static readonly RoutedEvent ExtendClickEvent = EventManager.RegisterRoutedEvent(nameof(ExtendClick), RoutingStrategy.Bubble,
                                                                        typeof(RoutedEventHandler), typeof(ImageTextBox));


    public event RoutedEventHandler ExtendClick
    {
        add { AddHandler(ExtendClickEvent, value); }
        remove { RemoveHandler(ExtendClickEvent, value); }
    }


    public static DependencyProperty ExtendButtonCommandProperty = DependencyProperty.Register(nameof(ExtendButtonCommand), typeof(ICommand), typeof(ImageTextBox));
    public ICommand ExtendButtonCommand
    {
        get { return (ICommand)GetValue(ExtendButtonCommandProperty); }
        set { SetValue(ExtendButtonCommandProperty, value); }
    }


    public static readonly DependencyProperty ExtendButtonCommandParameterProperty =
                                    DependencyProperty.Register(nameof(ExtendButtonCommandParameter), typeof(object), typeof(ImageTextBox), new UIPropertyMetadata(null));
    public object ExtendButtonCommandParameter
    {
        get { return (object)GetValue(ExtendButtonCommandParameterProperty); }
        set { SetValue(ExtendButtonCommandParameterProperty, value); }
    }


    public static readonly DependencyProperty ExtendButtonCommandTargetProperty =
                                DependencyProperty.Register(nameof(ExtendButtonCommandTarget), typeof(IInputElement), typeof(ImageTextBox), new UIPropertyMetadata(null));
    public IInputElement ExtendButtonCommandTarget
    {
        get { return (IInputElement)GetValue(ExtendButtonCommandTargetProperty); }
        set { SetValue(ExtendButtonCommandTargetProperty, value); }
    }
}

转换器ImageTextBoxMarginLeftConverter.cs

public class ImageTextBoxMarginLeftConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is double)
        {
            double v = (double)value;
            return v * 3.0 / 5.0;
        }
        return 0;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}


使用:

<StackPanel Orientation="Vertical" Grid.Row="1">
    <control:ImageTextBox x:Name="tbUserName" Width="200" Height="50" FontSize="30" Margin="5"
                        CornerRadius="12"
                        PlaceHolder="请输入用户名"
                        ExtendIconFontText="&#xe6d6;"
                        ExtendNormalImage="Resources/Images/MS.png"
                        ExtendHoverImage="Resources/Images/MS.png"
                        ExtendPressedImage="Resources/Images/MS.png"
                        ExtendDisabledImage="Resources/Images/MS.png"
                        Text="{Binding InputText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                        ExtendButtonCommand="{Binding BottonCommand}" ExtendButtonCommandParameter="button1 Click"/>
    <control:ImageTextBox x:Name="tbUserName1" Width="200" Height="50" Margin="5"
                        ExtendIconFontText="&#xe6d6;"
    CornerRadius="20" FontSize="20" Background="YellowGreen"
    PlaceHolder="请输入用户名"/>
    <control:ImageTextBox x:Name="tbUserName2" Width="200" Height="50" Margin="5"
                        ExtendNormalImage="Resources/Images/MS.png"
                        ExtendHoverImage="Resources/Images/MS.png"
                        ExtendPressedImage="Resources/Images/MS.png"
                        ExtendDisabledImage="Resources/Images/MS.png"
    PlaceHolder="请输入用户名"
    Image="Resources/Images/logo.png"/>
    <control:ImageTextBox x:Name="tbUserName3" Width="200" Height="50" Margin="5"
    PlaceHolder="请输入用户名" CornerRadius="20" IsEnabled="True"
    Image="Resources/Images/logo.png"/>
    <control:ImageTextBox x:Name="tbUserName4" Width="200" Height="50" Margin="5"
    PlaceHolder="请输入用户名" CornerRadius="20" IsEnabled="False"
    Image="Resources/Images/logo.png"/>


    <TextBox Width="200" Height="30" Margin="5"/>
</StackPanel>


        <!--校验错误提示模板-->
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <Border CornerRadius="3" BorderBrush="Red" BorderThickness="1">
                        <StackPanel Orientation="Vertical">
                            <AdornedElementPlaceholder x:Name="Adorned"/>
                            
                            <TextBlock Width="{TemplateBinding Width}" Foreground="Red" FontSize="16">  
                                <TextBlock.Text>
                                    <Binding ElementName="Adorned" Path="AdornedElement.(Validation.Errors)[0].ErrorContent"/>
                                </TextBlock.Text>  
                                <TextBlock.Effect>
                                    <DropShadowEffect Opacity="0.6" ShadowDepth="3" Color="Black"/>
                                </TextBlock.Effect>
                            </TextBlock>
                        </StackPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OneOnce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值