简体   繁体   中英

Placeholder Textbox Windows Phone 8

I have read this Adding placeholder text to textbox

The problem is, the placeholder TextBox must be easy to reuse. Either with XAML or Code. Maybe it's something like this

<my:TextBoxPlaceholder Placeholder="this is the placeholder"/>

or

<TextBox Placeholder="this is the placeholder"
         Type="/*staticresources*/PlaceholderTextBox"/>

This is what I'm referring to. (the screen shot I got from Instagram Beta).

伊姆古尔伊姆古尔

As you can see, on the second picture, the "Add a comment" placeholder is on the top most of TextBox, it covers the stripe line. Is the placeholder a picture or a TextBlock on top of it?

You can use the PhoneTextBox control from Windows Phone Toolkit .

It has a Hint property which allows you to set a placeholder:

<toolkit:PhoneTextBox Hint="Add a coment" Text={Binding ...} .../>

The third comment by MacGile on the thread you mentioned shows a fairly simple way to extend the normal TextBox with a special style. If you apply this style on your TextBox, you can use it simply as he illustrates:

<TextBox Style="{StaticResource placeHolder}" 
         Tag="Name of customer" Width="150" Height="24"/>

The Tag attribute is where you enter the placeholder text. The style is designed to change the color according to the text entered and will return to full color black when user edits.

A second way to achieve your goal is to place the TextBox in a Grid and add a TextBlock over it, which you will hide when the TextBlock is not empty (user has entered something). Sample:

<Grid>
   <TextBox x:Name="MyTextBox" />
   <TextBlock Text="enter name..." Foreground="#CCC" 
              Visibility="{Binding ElementName=MyTextBox, Path=Text, Converter={StaticResource StringLengthToVisibilityConverter}}" />
</Grid>

Where the StringLengthToVisibilityConverter is a IValueConverter that returns Visibility.Visible when the string parameter is empty. You can turn this into a custom control or UserControl and it will work just the way you need.

You can accomplish this with a WatermarkTextBox. First create a new class titled WatermarkTextBox.cs

public class WatermarkTextBox : TextBox
{
    public WatermarkTextBox()
    {
        TextChanged += OnTextChanged;    
    }

    private void OnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
    {
        // Show or hide the watermark based on the text length
        if (Text.Length > 0)
        {
            WatermarkVisibility = Visibility.Collapsed;
        }
        else
        {
            WatermarkVisibility = Visibility.Visible;
        }
    }

    public string Watermark
    {
        get { return (string)GetValue(WatermarkProperty); }
        set { SetValue(WatermarkProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Watermark.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty WatermarkProperty =
        DependencyProperty.Register("Watermark", typeof(string), typeof(WatermarkTextBox), new PropertyMetadata(null));

    public Visibility WatermarkVisibility
    {
        get { return (Visibility)GetValue(WatermarkVisibilityProperty); }
        set { SetValue(WatermarkVisibilityProperty, value); }
    }

    // Using a DependencyProperty as the backing store for WatermarkVisibility.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty WatermarkVisibilityProperty =
        DependencyProperty.Register("WatermarkVisibility", typeof(Visibility), typeof(WatermarkTextBox), new PropertyMetadata(System.Windows.Visibility.Visible));
}

In your xaml, use this in place of your normal Textbox

<controls:WatermarkTextBox Watermark="Add a comment" Text="{Binding MyProperty}" Style={StaticResource WaterMarkTextBoxStyle/>

Notice the style defined, add the following style to your app.xaml

<Style x:Key="WatermarkTextBoxStyle" TargetType="local:WatermarkTextBox">
    <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
    <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
    <Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/>
    <Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/>
    <Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/>
    <Setter Property="SelectionBackground" Value="{StaticResource PhoneAccentBrush}"/>
    <Setter Property="SelectionForeground" Value="{StaticResource PhoneTextBoxSelectionForegroundBrush}"/>
    <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
    <Setter Property="Padding" Value="2"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:WatermarkTextBox">
                <Grid Background="Transparent">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver"/>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="MainBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="MainBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="ReadOnly">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="MainBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Collapsed</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ReadonlyBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ReadonlyBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ReadonlyBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxReadOnlyBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="MainBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="MainBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Unfocused"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="MainBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}"/>
                    <Border x:Name="ReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed"/>
                    <Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}">
                        <Grid>
                            <ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/>
                            <TextBlock Text="{TemplateBinding Watermark}"  Foreground="Gray" Margin="3,4,0,0" Visibility="{TemplateBinding WatermarkVisibility}"/>
                        </Grid>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM