WaterTextBox 带密码

带水印、带密码的输入框,示例:
这里写图片描述

  public class WaterTextBox : TextBox
    {
        static WaterTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(WaterTextBox), new FrameworkPropertyMetadata(typeof(WaterTextBox)));
        }

        /// <summary>
        /// 水印文字
        /// </summary>
        public string WaterText
        {
            get { return GetValue(WaterTextProperty).ToString(); }
            set { SetValue(WaterTextProperty, value); }
        }
        public static DependencyProperty WaterTextProperty =
                   DependencyProperty.Register("WaterText", typeof(string), typeof(WaterTextBox));

        /// <summary>
        /// 水印前景色
        /// </summary>
        public Brush WaterTextForeground
        {
            get { return (Brush)GetValue(WaterTextForegroundProperty); }
            set { SetValue(WaterTextForegroundProperty, value); }
        }

        public static readonly DependencyProperty WaterTextForegroundProperty =
            DependencyProperty.Register("WaterTextForeground", typeof(Brush), typeof(WaterTextBox),new PropertyMetadata(Brushes.Gainsboro));



        /// <summary>
        /// 边框角度
        /// </summary>
        public CornerRadius BorderCornerRadius
        {
            get { return (CornerRadius)GetValue(BorderCornerRadiusProperty); }
            set { SetValue(BorderCornerRadiusProperty, value); }
        }

        public static DependencyProperty BorderCornerRadiusProperty =
            DependencyProperty.Register("BorderCornerRadius", typeof(CornerRadius), typeof(WaterTextBox));



        /// <summary>
        /// 密码符号
        /// </summary>
        public char PasswordChar
        {
            get { return (char)GetValue(PasswordCharProperty); }
            set { SetValue(PasswordCharProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PasswardChar.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PasswordCharProperty =
            DependencyProperty.Register("PasswardChar", typeof(char), typeof(WaterTextBox), new PropertyMetadata('*'));



        /// <summary>
        /// 密码
        /// </summary>
        public string Password
        {
            get { return (string)GetValue(PasswordProperty); }
            set { SetValue(PasswordProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Password.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PasswordProperty =
            DependencyProperty.Register("Password", typeof(string), typeof(WaterTextBox),new PropertyMetadata(string.Empty));


        /// <summary>
        /// 是否是密码框
        /// </summary>
        public bool IsPasswordBox
        {
            get { return (bool)GetValue(IsPasswordBoxProperty); }
            set { SetValue(IsPasswordBoxProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsPasswordBox.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsPasswordBoxProperty =
            DependencyProperty.Register("IsPasswordBox", typeof(bool), typeof(WaterTextBox), new PropertyMetadata(false,
                (d, e) =>
                {
                    var oldValue = (bool)e.OldValue;
                    var newValue = (bool)e.NewValue;
                    var sender = d as WaterTextBox;
                    if (sender != null && oldValue != newValue)
                    {
                        if (newValue)
                        {
                            sender.TextChanged += Password_TextChanged;
                            InputMethod.SetIsInputMethodEnabled(sender, false);
                        }
                        else
                        {
                            sender.TextChanged -= Password_TextChanged;
                            InputMethod.SetIsInputMethodEnabled(sender, true);
                            sender.Text = sender.Password;
                        }
                    }
                }));

        private static void Password_TextChanged(object sender, TextChangedEventArgs e)
        {
            var textBox = sender as WaterTextBox;
            if (!string.IsNullOrWhiteSpace(textBox.Text))
            {
                if (textBox.Text == textBox.WaterText) return;

                Action<WaterTextBox, int, int> setNewValue = (tb, newC, newS) =>
                    {
                        var newText = string.Empty;
                        for (int i = 0; i < newC; i++)
                        {
                            newText += textBox.PasswordChar;
                        }
                        tb.Text = newText;
                        tb.SelectionStart = newS;
                    };

                var lastInput = textBox.Password;
                var selectionStart = textBox.SelectionStart;
                var newChars = textBox.Text.ToList();
                var newChar = newChars.Find(i => i != textBox.PasswordChar);
                if (newChar != 0)//新输入字符
                {
                    var newCharIndex = newChars.IndexOf(newChar);
                    if (newCharIndex > 0)
                    {
                        textBox.Password = lastInput.Insert(newCharIndex, newChar.ToString());
                    }
                    else
                    {
                        textBox.Password = newChar.ToString();
                    }
                    setNewValue(textBox, newChars.Count, selectionStart);
                }
                else//没有新输入字符串或新输入字符和密码字符一样
                {
                    if (lastInput.Length < newChars.Count)//输入了新字符且和密码字符一样
                    {
                        textBox.Password = lastInput.Insert(textBox.SelectionStart - 1, textBox.PasswordChar.ToString());
                        setNewValue(textBox, newChars.Count, selectionStart);
                    }
                    else if (lastInput.Length > newChars.Count)//没有输入字符且删除了一个字符
                    {
                        if (lastInput.Length == textBox.SelectionStart)//删除了最后一个字节
                        {
                            textBox.Password = lastInput.Remove(lastInput.Length - 1, 1);
                        }
                        else//删除了非最后一个字节
                        {
                            textBox.Password = lastInput.Remove(textBox.SelectionStart, 1);
                        }
                        setNewValue(textBox, newChars.Count, selectionStart);
                    }
                }
            }
            else
            {
                textBox.Password = string.Empty;
            }

        }
    }

style:

 <Style TargetType="local:WaterTextBox">
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="BorderBrush" Value="Gray"/>
        <Setter Property="Cursor" Value="IBeam"/>
        <Setter Property="Padding" Value="4 0 0 0"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:WaterTextBox">
                    <Border x:Name="border"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}"
                                CornerRadius="{TemplateBinding BorderCornerRadius}"  
                        SnapsToDevicePixels="True">
                        <Grid>
                            <ScrollViewer x:Name="PART_ContentHost" Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                            <TextBlock x:Name="txtRemark" Text="{TemplateBinding WaterText}"  
                                           Foreground="{TemplateBinding WaterTextForeground}" VerticalAlignment="Center"
                                           Margin="8 0 0 0"
                                           Visibility="Collapsed"/> <!--默认水印文字隐藏-->
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="Text" Value="">
                            <!--使用触发器来控制水印的隐藏显示:当文本框没有字符时显示水印文字-->
                            <Setter Property="Visibility" Value="Visible" TargetName="txtRemark"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CSKIN-15.1.28 1.优化SkinTabControl标签移入移出效果。 2.将SkinTextBox改为容器边框,其他控件可放进其里面。 3.设置SkinTextBox中的TextBox为不可点击,详细参数在属性栏里设置。 4.SkinPanel添加属性(BorderColor:边框颜色)。 5.添加(SkinPushPanel:抽屉控件列表,根据Items添加。)和(SkinCaptionPanel:面板控件单独)。 6.添加(SkinCode:验证码控件。)。 7.减少SkinTreeView的闪烁。 8.窗体XP下最大化移动BUG修复。 9.修复SkinButton的禁止状态绘制不显示的问题。 10.修复SkinDataGridView的一些设置BUG。 11.修复SkinRadioButton属性Text为空报错问题。 12.修复属性(Shadow:是否启用窗体阴影)。 13.加入(日期面板控件:SkinMonthCalendar),(日期选择框控件:SkinDateTimePicker)。 14.加入(弹出承载控件:SkinDropDown) 使用方法: SkinDropDown _SkinDropDown = new SkinDropDown(控件:Control); _SkinDropDown.Show(new Point(0, 22)); 15.添加SystemInformationHelper静态类,获得操作系统版本。 16.添加控件(SkinHotKey:自定义热键注册控件)。 17.窗体添加属性(XTheme:窗体主题,类型:继承CCSkinMain的窗体),增加皮肤更换属性,更好的对换肤支持。 18.增加了MDI支持,并多了一些属性设置MDI。 19.对好友列表进行了绘制优化,效率MAX,真正达到了千人不卡。 20.好友列表添加属性(SmoothScroll:是否平滑滚动),对好友列表加入平滑滚动的效果。 21.修复异形窗体SkinMain不可在透明区域放控件的BUG。 22.好友列表好友拖动效果优化。 23.解决SkinMain异形窗体无法点击触发点击事件问题。 24.修复SkinToolTip的字体颜色及大小BUG。 CSKIN-14.8.26 1.修复SkinPanel滚动条不显示的问题。 2.修复SkinPanel右下边框不显示的问题。 3.修复好友列表头像闪烁的一些BUG。 4.修复SkinMain异形窗体点击任务栏最小化操作。 5.加入内置工具类FastBitmap,此类用来快速Bitmap读写像素,如何使用看:http://bbs.cskin.net/thread-83-1-1.html。 6.修复截图控件的未选框双击错误BUG,增加截图控件属性BmpLayerCurrent:控件所截图的图片。 7.SkinToolStrip添加BaseItemNorml属性,BaseItem默认背景图。 8.修复SkinComboBox下拉框项的细节样式。 9.加入SkinFileTansfersContainer控件与SkinFileTransfersItem控件。 SkinFileTansfersContainer:文件传输列表容器,这里面内置Add,Remove,Search等操作ItemList方法。 SkinFileTransfersItem:文件传输列表项,用于添加进列表容器。 10.SkinToolStrip控件添加BindTabControl=(绑定要操作的TabControl)属性,绑定后点击ToolStripButton就可以根据ToolStripButton中的Tag=(TabPage的Index值)进行切换TabPage。 11.优化设计时SkinTabControl略卡的问题。 12.SkinTabePage添加属性(BorderColor:边框颜色)。 13.修复好友列表闪烁状态下好友被删除,分组依然闪烁。 14.SkinButton、SkinCheckBox、SkinRadioButton添加属性(IsEnabledDraw:是否画禁用状态下的效果,默认true)。 15.好友列表添加三个事件: (DownSubItem:用鼠标按下子项时发生) (UpSubItem:用鼠标按下并释放子项时发生) (ClickSubItem:用鼠标单击子项时发生) 16.SkinTabControl添加两个事件: (TabePageClosed:TabPage容器关闭后。) (TabePageClosing:TabPage容器关闭前。) 17.加入彗星小助手案例DEMO。 CSKIN-14.7.2 1.SkinTabContro
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值