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

来源:互联网 发布:java setlayout 编辑:程序博客网 时间:2024/06/10 09:54

效果:



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>


原创粉丝点击