占位符文本框 Windows Phone 8

Posted

技术标签:

【中文标题】占位符文本框 Windows Phone 8【英文标题】:Placeholder Textbox Windows Phone 8 【发布时间】:2014-03-08 12:18:07 【问题描述】:

我读过这个 Adding placeholder text to textbox

问题是,占位符 TextBox 必须易于重用。使用 XAML 或代码。 也许是这样的

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

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

这就是我所指的。 (我从 Instagram Beta 获得的屏幕截图)。

如您所见,在第二张图片中,“添加评论”占位符位于 TextBox 的最顶部,它覆盖了条纹线。占位符是图片还是上面的TextBlock?

【问题讨论】:

【参考方案1】:

MacGile 在您提到的线程上的第三条评论显示了一种相当简单的方法来扩展具有特殊样式的普通 TextBox。如果你在你的 TextBox 上应用这种风格,你可以像他说明的那样简单地使用它:

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

Tag 属性是您输入占位符文本的位置。该样式旨在根据输入的文本更改颜色,并在用户编辑时恢复为全黑。

实现目标的第二种方法是将 TextBox 放在 Grid 中并在其上添加一个 TextBlock,当 TextBlock 不为​​空(用户输入了某些内容)时,您将隐藏它。示例:

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

其中StringLengthToVisibilityConverterIValueConverter,当字符串参数为空时返回Visibility.Visible。您可以将其转换为自定义控件或 UserControl,它会按照您需要的方式工作。

【讨论】:

【参考方案2】:

您可以使用来自Windows Phone Toolkit 的PhoneTextBox 控件。

它有一个Hint 属性,可让您设置占位符:

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

【讨论】:

使用PhoneTextBox的缺点是当有键盘焦点时文本会消失 我还发现这个控件在前景色方面有问题。要复制,请按照上面的操作,添加提示,F5,输入文本框,添加文本,然后按退格键直到没有更多文本,然后再次输入星号,文本将变为灰色而不是黑色。 有没有办法在texbox收到焦点时保留提示文本??【参考方案3】:

您可以使用 WatermarkTextBox 完成此操作。首先新建一个名为 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));

在您的 xaml 中,使用它代替您的普通文本框

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

注意定义的样式,将以下样式添加到您的 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>

【讨论】:

以上是关于占位符文本框 Windows Phone 8的主要内容,如果未能解决你的问题,请参考以下文章

如何填充文本框-Windows Phone 8.1

Windows phone 8.1 - 来自动态创建的文本框的文本

Windows Phone 8 滚动文本框的内容

Windows Phone 8上的文本换行列表框

用户文本框中的占位符/示例文本

文本框的占位符警告