Question

I need WatermarkPasswordBox control but there is not in Winrt. Maybe we can add Watermark property to PasswordBox. Are there anyone who can do it?

Thanks

Was it helpful?

Solution 3

UPDATE 1

If you don't want to use 3rd party DLL, add these two methods in PasswordBoxBehavior.cs file.

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);
}

Here's extensive blog from JulMar

Adding a watermark to a PasswordBox in a Windows Store app

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

OTHER TIPS

The purpose of a watermark is to convey a message behind the control. In the case of this demonstration, the watermark also dissappear after you start typing text, so they are more like a field "hint" telling you what is expected.

To achieve this, we turn to a regular WPF solution provider, the AttachedProperty. AttachedProperties allow you to add extra properties to any control. You can also extend it into an Attachedbehaviour, where you are making the control react to changes to the property.

In this example, we use two attached properties. The first "WaterrmarkProperty" to take the watermark value and initialise the control:

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));

The second attached property is to notify whether there is a value in the box, which the template binds to and hides or shows the watermark.

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));

For the TextBoxHelper, whenever the text is changed, the watermark is shown or hidden as follows:

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

This is controlled by the 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>

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

In Windows 8.0 you can use the WatermarkPasswordBox from WinRT XAML Toolkit, which you can get from here. It gives you a Watermark property to set any UI element (Shape, Image, etc.) as a watermark or WatermarkText property that takes a text and WatermarkTextStyle that takes a TextBlock Style to style the text.

In Windows 8.1 you can use the same or use the new PlaceholderText property.

Feel free to rip out and modify the WatermarkPasswordBox control's code from the library and use it in your app. It's MIT licensed. No credits required. Just take the .cs and .xaml files and include the .xaml resource dictionary in your Themes/Generic.xaml like so:

<ResourceDictionary
        Source="ms-appx:///YourControlsLibraryNamefNotInMainApp/RelativeDirectoryPathOfTheFile/WatermarkPasswordBox.xaml" />
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top