zoukankan      html  css  js  c++  java
  • silverlight带水印的自定义TextBox控件(版本2)

    之前那个版本《silverlight-带水印的TextBox》不得不说是相当失败的,起码我是这样理解的。其实我一心想把这个给实现了,但是不得不承认自身技术上的缺陷。经过一番尝试和折腾,有了下面这个版本。

    两个版本的区别:

    其实是有本质的区别的。

    之前那个版本只能设置“文本水印”,相当有局限性。现在的版本是可以自定义水印内容的。譬如,可以为button,rectangle,ellipsed... 

    1.先新建一个“silverlight 模板化控件”,取名随意,此处为SuperText

    2.修改继承的类Contol为TextBox

    3.修改TextBox模板

    控件SuperTextBox的模板,样式都是保存在一个叫“Generic.xaml”文件里面的。在第一次新建“silverlight 模板化控件”的时候,这个文件会自动产生。这里将TextBox的模板添加进入,并修改。

    完整的

    完整的Generic.xaml
    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:local="clr-namespace:TextBoxWaterMark">
    
    
        <Style TargetType="local:SuperTextBox">
    
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Background" Value="#FFFFFFFF"/>
            <Setter Property="Foreground" Value="#FF000000"/>
            <Setter Property="Padding" Value="2"/>
            <Setter Property="BorderBrush">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFA3AEB9" Offset="0"/>
                        <GradientStop Color="#FF8399A9" Offset="0.375"/>
                        <GradientStop Color="#FF718597" Offset="0.375"/>
                        <GradientStop Color="#FF617584" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:SuperTextBox">
                        <Grid x:Name="RootElement">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="MouseOverBorder" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" To="#FF99C1E2" Duration="0"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity" To="1" Duration="0"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="ReadOnly">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="ReadOnlyVisualElement" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates">
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity" To="1" Duration="0"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unfocused">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity" To="0" Duration="0"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="ValidationStates">
                                    <VisualState x:Name="Valid"/>
                                    <VisualState x:Name="InvalidUnfocused">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="InvalidFocused">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsOpen">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <sys:Boolean>True</sys:Boolean>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
    
                                <VisualStateGroup x:Name="WatermarkDisplayed">
                                    <VisualState x:Name="Hidden">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="watermarkContent" Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Shown">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="watermarkContent" Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1" />
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                
                            </VisualStateManager.VisualStateGroups>
                            
                            <Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
                                <Grid>
                                    
                                    <UserControl x:Name="watermarkContent" Content="{TemplateBinding Watermark}"/>
                                    
                                    <Border x:Name="ReadOnlyVisualElement" Opacity="0" Background="#5EC9C9C9"/>
                                    <Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent">
                                        <ScrollViewer x:Name="ContentElement" Padding="{TemplateBinding Padding}" BorderThickness="0" IsTabStop="False"/>
                                    </Border>
                                </Grid>
                            </Border>
                            <Border x:Name="DisabledVisualElement" Background="#A5F7F7F7" BorderBrush="#A5F7F7F7" BorderThickness="{TemplateBinding BorderThickness}" Opacity="0" IsHitTestVisible="False"/>
                            <Border x:Name="FocusVisualElement" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}" Margin="1" Opacity="0" IsHitTestVisible="False"/>
                            <Border x:Name="ValidationErrorElement" BorderThickness="1" CornerRadius="1" BorderBrush="#FFDB000C" Visibility="Collapsed">
                                <Grid Width="12" Height="12" HorizontalAlignment="Right" Margin="1,-4,-4,0" VerticalAlignment="Top" Background="Transparent">
                                    <Path Margin="1,3,0,0" Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C"/>
                                    <Path Margin="1,3,0,0" Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff"/>
                                </Grid>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
    
        </Style>
    </ResourceDictionary>

     在上面的"Generic.xaml"文件的SuperTextBox模板中修改新增了一下内容

    • 新增一个UserControl,即水印内容。

    取名随意,这里为“watermarkContent”,并且绑定Content属性为“WaterMark”

    <UserControl x:Name="watermarkContent" Content="{TemplateBinding Watermark}"/>
    •  增加两个状态

    状态为了控制水印是否出现。其实本质是调节水印的透明度。

    <VisualStateGroup x:Name="WatermarkDisplayed">
        <VisualState x:Name="Hidden">
            <Storyboard>
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="watermarkContent" Storyboard.TargetProperty="(UIElement.Opacity)">
                    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </VisualState>
        <VisualState x:Name="Shown">
            <Storyboard>
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="watermarkContent" Storyboard.TargetProperty="(UIElement.Opacity)">
                    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1" />
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </VisualState>
    </VisualStateGroup>

    4.在托管代码中

    • 因为模板中绑定了一个新的属性WaterMark,所以需要在托管代码进行注册。并且用属性Watermark保存。
    public object Watermark
    {
        get { return base.GetValue(WatermarkProperty) as object; }
        set { base.SetValue(WatermarkProperty, value); }
    }
    
    //向空间增加property 
    public static readonly DependencyProperty WatermarkProperty =
    DependencyProperty.Register("Watermark", typeof(object), typeof(SuperTextBox), new PropertyMetadata(null));
    • 为了控制水印状态需要增加一个TextChanged事件。
    public SuperTextBox()
    {
        this.DefaultStyleKey = typeof(SuperTextBox);
        TextChanged += new TextChangedEventHandler(SuperTextBox_TextChanged);
    }
    
    void SuperTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBox tb = (TextBox)sender;
        if (tb.Text.Length > 0)
        {
            System.Windows.VisualStateManager.GoToState(tb, "Hidden", false);
        }
        else
        {
            System.Windows.VisualStateManager.GoToState(tb, "Shown", false);
        } 
    }
    • 完整托管代码
    完整的SuperTextBox托管代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Collections.ObjectModel;
    
    namespace TextBoxWaterMark
    {
        public class SuperTextBox : TextBox
        {
    
            public object Watermark
            {
                get { return base.GetValue(WatermarkProperty) as object; }
                set { base.SetValue(WatermarkProperty, value); }
            }
    
            //向空间增加property 瓶颈所在
            public static readonly DependencyProperty WatermarkProperty =
            DependencyProperty.Register("Watermark", typeof(object), typeof(SuperTextBox), new PropertyMetadata(null));
    
    
            public SuperTextBox()
            {
                this.DefaultStyleKey = typeof(SuperTextBox);
                TextChanged += new TextChangedEventHandler(SuperTextBox_TextChanged);
            }
    
            void SuperTextBox_TextChanged(object sender, TextChangedEventArgs e)
            {
                TextBox tb = (TextBox)sender;
                if (tb.Text.Length > 0)
                {
                    System.Windows.VisualStateManager.GoToState(tb, "Hidden", false);
                }
                else
                {
                    System.Windows.VisualStateManager.GoToState(tb, "Shown", false);
                } 
            }
    
            public override void  OnApplyTemplate()
            {
                base.OnApplyTemplate();
            }
    
        }
    
    }

    5.调用

    <local:SuperTextBox Height="20">
                    <local:SuperTextBox.Watermark>
                        <StackPanel Orientation="Horizontal" Opacity="0.4">
                            <Rectangle Fill="Red" Width="10" Height="10"/>
                            <TextBlock Text="我是一个水印"/>
                        </StackPanel>
                    </local:SuperTextBox.Watermark>
                </local:SuperTextBox>

    需加上命名空间local,local指向的是SuperTextBox所在的命名空间。

    6.效果

    参考资料:《[控件问题] TextBox控件的Watermark问题变通解决方法
    silverlight-带水印的TextBox
     
    人生苦短,虚心求教
  • 相关阅读:
    换空间后如何导入MYSQL数据库
    从robots文件看网站用的是哪个程序
    DEDEcms二次开发数据表参数
    DEDE常用配置
    织梦CMS站点favicon.ico图标的放置
    dedecms列表页如何让文章列表里面的文章每隔五篇就隔开一段空间
    Dedecms 5.7如何制作网站地图?
    dede上怎么让所有链接在新窗口打开
    dede织梦列表页如何调用全站子栏目
    《DSP using MATLAB》示例Example 8.4
  • 原文地址:https://www.cnblogs.com/rond/p/2652271.html
Copyright © 2011-2022 走看看