2

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

谢谢

4

3 回答 3

2

在 Windows 8.0 中,您可以使用WatermarkPasswordBoxWinRT XAML 工具包,您可以从此处获取。它为您提供了一个Watermark属性,可以将任何 UI 元素(ShapeImage等)设置为水印或WatermarkText属性,该属性采用文本并WatermarkTextStyle采用 aTextBlock Style来设置文本的样式。

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

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

<ResourceDictionary
        Source="ms-appx:///YourControlsLibraryNamefNotInMainApp/RelativeDirectoryPathOfTheFile/WatermarkPasswordBox.xaml" />
于 2013-07-11T02:10:58.193 回答
2

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

为了实现这一点,我们求助于常规的 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

于 2013-07-10T12:46:47.860 回答
1

更新 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 的大量博客

在 Windows 应用商店应用中向 PasswordBox 添加水印

如果您想自己使用它,这是代码。

于 2013-07-10T13:10:04.770 回答