【问题标题】:How can I add WaterMark property to PasswordBox in Winrt?如何在 Winrt 中将 WaterMark 属性添加到 PasswordBox?
【发布时间】:2013-07-10 12:41:38
【问题描述】:

我需要 WatermarkPasswordBox 控件,但 Winrt 中没有。也许我们可以将 Watermark 属性添加到 PasswordBox。有人能做到吗?

谢谢

【问题讨论】:

    标签: textbox windows-runtime watermark maskedtextbox passwordbox


    【解决方案1】:

    水印的目的是在控件背后传达信息。在本演示中,水印在您开始输入文本后也会消失,因此它们更像是一个“提示”字段,告诉您预期的内容。

    为了实现这一点,我们求助于常规的 WPF 解决方案提供商,即 AttachedProperty。 AttachedProperties 允许您向任何控件添加额外的属性。您还可以将其扩展为 Attachedbehaviour,让控件对属性的更改做出反应。

    在本例中,我们使用了两个附加属性。第一个“WaterrmarkProperty”取水印值并初始化控件:

    public static string GetWatermark(DependencyObject obj) 
    { 
        return (string)obj.GetValue(WatermarkProperty); 
    } 
    
    public static void SetWatermark(DependencyObject obj, string value) 
    { 
        obj.SetValue(WatermarkProperty, value); 
    } 
    
    public static readonly DependencyProperty WatermarkProperty = 
        DependencyProperty.RegisterAttached("Watermark", typeof(string), typeof(TextBoxHelper), new UIPropertyMetadata(null, WatermarkChanged));
    

    第二个附加属性是通知框内是否有值,模板绑定并隐藏或显示水印。

    public static bool GetShowWatermark(DependencyObject obj) 
    { 
        return (bool)obj.GetValue(ShowWatermarkProperty); 
    } 
    
    public static void SetShowWatermark(DependencyObject obj, bool value) 
    { 
        obj.SetValue(ShowWatermarkProperty, value); 
    } 
    
    public static readonly DependencyProperty ShowWatermarkProperty = 
        DependencyProperty.RegisterAttached("ShowWatermark", typeof(bool), typeof(TextBoxHelper), new UIPropertyMetadata(false));
    

    对于TextBoxHelper,每当文本发生变化时,水印就会显示或隐藏,如下所示:

    private static void CheckShowWatermark(TextBox box) 
    { 
        box.SetValue(TextBoxHelper.ShowWatermarkProperty, box.Text == string.Empty); 
    } 
    

    这由 ControlTemplate 控制:

    <ControlTemplate x:Key="WatermarkedTextBoxTemplate" TargetType="{x:Type TextBox}"> 
        <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true"> 
            <Grid> 
                <TextBlock Text="{Binding Path=(local:TextBoxHelper.Watermark), RelativeSource={RelativeSource TemplatedParent}}" Opacity=".5" FontWeight="Bold" Visibility="{Binding (local:TextBoxHelper.ShowWatermark), Converter={StaticResource BooleanToVisibilityConverter}, RelativeSource={RelativeSource TemplatedParent}}" /> 
                <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
            </Grid> 
        </Microsoft_Windows_Themes:ListBoxChrome> 
        <ControlTemplate.Triggers> 
            <Trigger Property="IsEnabled" Value="false"> 
                <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> 
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
            </Trigger> 
        </ControlTemplate.Triggers> 
    </ControlTemplate>
    

    来源:http://code.msdn.microsoft.com/windowsdesktop/Watermarked-TextBox-and-444ebdec

    【讨论】:

    • 我正在尝试,谢谢。试用后我会回复你的。
    • 没有一个名为 UIPropertyMetadata 的类?
    • 您使用哪种语言?
    • Winrt :) 我看过它们,但它们都没有运行。只有 JulMar 的代码在运行,但他使用的是他自己的 DLL,我无法在我的银行应用程序中使用外部 dll。
    【解决方案2】:

    在 Windows 8.0 中,您可以使用来自 WinRT XAML 工具包的WatermarkPasswordBox,您可以从here 获得该工具包。它为您提供了一个 Watermark 属性来将任何 UI 元素(ShapeImage 等)设置为水印或采用文本的 WatermarkText 属性和采用 TextBlockWatermarkTextStyle 属性设置文本样式。

    在 Windows 8.1 中,您可以使用相同的属性或使用新的 PlaceholderText 属性。

    随意从库中删除和修改WatermarkPasswordBox 控件的代码,并在您的应用程序中使用它。它是麻省理工学院许可的。不需要学分。只需获取 .cs 和 .xaml 文件并将 .xaml 资源字典包含在您的 Themes/Generic.xaml 中,如下所示:

    <ResourceDictionary
            Source="ms-appx:///YourControlsLibraryNamefNotInMainApp/RelativeDirectoryPathOfTheFile/WatermarkPasswordBox.xaml" />
    

    【讨论】:

    • 谢谢@Filip,我正在等待 PlaceHolderText 属性 :)
    【解决方案3】:

    更新 1

    如果您不想使用 3rd 方 DLL,请将这两个方法添加到 PasswordBoxBehavior.cs 文件中。

    using System.Reflection;
    
    public static T FindVisualChildByName<T>(this DependencyObject fe, string name) where T : DependencyObject
    {
        if (string.IsNullOrEmpty(name))
        {
            throw new ArgumentNullException("name");
        }
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(fe); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(fe, i);
            string a = child.GetValue(FrameworkElement.NameProperty) as string;
            if (a == name)
            {
                return child as T;
            }
            T t = FindVisualChildByName<T>(child, name);
            if (t != null)
            {
                return t;
            }
        }
        return default(T);
    }
    
    public static T FindVisualParent<T>(this DependencyObject fe) where T : DependencyObject
    {
        for (fe = VisualTreeHelper.GetParent(fe); fe != null; fe = VisualTreeHelper.GetParent(fe))
        {
            T t = fe as T;
            if (t != null)
            {
                return t;
            }
        }
        return default(T);
    }
    

    这是来自 JulMar 的大量博客

    Adding a watermark to a PasswordBox in a Windows Store app

    Here’s the code if you’d like to use it yourself.

    【讨论】:

    • 他正在使用他自己的 DLL,我无法在我的银行应用程序中使用外国 dll。 :(
    • 欢迎 Tuğrul Emre Atalay :)
    • 我也有问题 Farhan,如何在 Resource.resw 中给它的水印属性(CustomControls:PasswordBoxBehavior.Watermark="Enter Password...")?像 x:Uid="test.Watermark",但它给出了运行时错误,即 Watermark 属性不在 PasswordBox 中。我已经在资源中更改了 Test.MakePaymentAppBar.[using:Windows8.StoreApp.Common.CustomControls]PasswordBoxBehavior.Watermark 但它没有运行。
    • 我有一个 UserControl,它有一个 StackPanel,它有 2 个 watermarkpasswordbox。我正在使用“PasswordBoxBehavior.SetValue(mypwBox,”myvalue”);”设置我的 watermarkpasswordboxes 水印值在“初始化组件();”下但是没有focus-unfocus就不会出现水印。请问你能帮帮我吗?为什么我的水印在失焦后没有出现失焦?
    • &lt;PasswordBox /&gt;中设置IsTabStop="False"
    猜你喜欢
    • 2013-07-20
    • 1970-01-01
    • 2013-06-29
    • 2022-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    相关资源
    最近更新 更多