我需要在我的一个文本框中添加占位符,我通过在文本框中包含不透明度较低的文本和占位符文本来完成它,然后在文本框的焦点上删除占位符文本的内容并增加不透明度到1。 我在这里有一个问题,如果用户没有在该字段中输入任何内容并提交输入,则不会触发onfocus事件,因此占位符文本将作为文本框的值发送。如何解决此问题?
答案 0 :(得分:3)
如果您不想使用图像水印,请查看以下解决方案。
Windows Phone 7 Silverlight Watermark TextBox Control
Windows Phone Watermark TextBox Control
由于仅链接答案在SO中无效,我发布了第二个链接的代码,因为我已经使用过了。
WatermarkTextBox.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
namespace System.Windows.Controls
{
[StyleTypedProperty(Property = "WatermarkTextStyle", StyleTargetType = typeof(TextBlock)),
TemplatePart(Name = "WatermarkText", Type = typeof(TextBlock)),
TemplateVisualState(Name = "WatermarkTextVisible", GroupName = "WatermarkTextStates"),
TemplateVisualState(Name = "WatermarkTextHidden", GroupName = "WatermarkTextStates")]
public class WatermarkTextBox : TextBox
{
public static readonly DependencyProperty WatermarkTextProperty = DependencyProperty.Register(
"WatermarkText",
typeof(string),
typeof(WatermarkTextBox),
new PropertyMetadata("", OnWatermarkTextPropertyChanged));
public static readonly DependencyProperty WatermarkTextForegroundProperty = DependencyProperty.Register(
"WatermarkTextForeground",
typeof(Brush),
typeof(WatermarkTextBox),
new PropertyMetadata(new SolidColorBrush(Colors.Gray), OnWatermarkTextForegroundPropertyChanged));
public static readonly DependencyProperty WatermarkTextStyleProperty = DependencyProperty.Register(
"WatermarkTextStyle",
typeof(Style),
typeof(WatermarkTextBox),
new PropertyMetadata(null, OnWatermarkTextStylePropertyChanged));
private bool itsIsFocused = false;
public string WatermarkText
{
get { return (string)this.GetValue(WatermarkTextProperty); }
set { this.SetValue(WatermarkTextProperty, value); }
}
public Brush WatermarkTextForeground
{
get { return (Brush)this.GetValue(WatermarkTextForegroundProperty); }
set { this.SetValue(WatermarkTextForegroundProperty, value); }
}
public Style WatermarkTextStyle
{
get { return (Style)this.GetValue(WatermarkTextStyleProperty); }
set { this.SetValue(WatermarkTextStyleProperty, value); }
}
private static void OnWatermarkTextPropertyChanged(DependencyObject theTarget, DependencyPropertyChangedEventArgs theDependencyPropertyChangedEventArgs)
{
// Do nothing
}
private static void OnWatermarkTextForegroundPropertyChanged(DependencyObject theTarget, DependencyPropertyChangedEventArgs theDependencyPropertyChangedEventArgs)
{
// Do nothing
}
private static void OnWatermarkTextStylePropertyChanged(DependencyObject theTarget, DependencyPropertyChangedEventArgs theDependencyPropertyChangedEventArgs)
{
// Do nothing
}
public WatermarkTextBox()
: base()
{
this.DefaultStyleKey = typeof(WatermarkTextBox);
this.GotFocus += new RoutedEventHandler(WatermarkTextBox_GotFocus);
this.LostFocus += new RoutedEventHandler(WatermarkTextBox_LostFocus);
this.Loaded += new RoutedEventHandler(WatermarkTextBox_Loaded);
this.TextChanged += new TextChangedEventHandler(WatermarkTextBox_TextChanged);
}
private void WatermarkTextBox_Loaded(object sender, RoutedEventArgs e)
{
this.GoToVisualState(true);
}
private void WatermarkTextBox_GotFocus(object sender, RoutedEventArgs e)
{
this.itsIsFocused = true;
this.GoToVisualState(false);
}
private void WatermarkTextBox_LostFocus(object sender, RoutedEventArgs e)
{
this.itsIsFocused = false;
this.GoToVisualState(true);
}
private void WatermarkTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (!this.itsIsFocused)
{
this.GoToVisualState(false);
}
}
private void GoToVisualState(bool theIsWatermarkDisplayed)
{
if (theIsWatermarkDisplayed && (this.Text == null || (this.Text != null && this.Text.Length == 0)))
{
VisualStateManager.GoToState(this, "WatermarkTextVisible", true);
}
else
{
VisualStateManager.GoToState(this, "WatermarkTextHidden", true);
}
}
}
}
在资源字典中添加样式。
在xmlns:controls="clr-namespace:System.Windows.Controls;assembly=YOUR_PROJECT_ASSEMBLY_NAME"
<App />
<Style TargetType="controls: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="WatermarkTextForeground" Value="#FF868686" />
<Setter Property="WatermarkTextStyle">
<Setter.Value>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="20,0,0,0" />
<Setter Property="TextWrapping" Value="NoWrap" />
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:WatermarkTextBox">
<Grid Background="Transparent">
<Grid.Resources>
<ControlTemplate x:Key="PhoneDisabledTextBoxTemplate" TargetType="controls:WatermarkTextBox">
<ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/>
</ControlTemplate>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="ReadOnly">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="DisabledOrReadonlyBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="DisabledOrReadonlyBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DisabledOrReadonlyContent">
<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="EnabledBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="EnabledBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
<VisualStateGroup x:Name="WatermarkTextStates">
<VisualState x:Name="WatermarkTextVisible">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="WatermarkTextBlock" Storyboard.TargetProperty="(UIElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="WatermarkTextHidden">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="WatermarkTextBlock" Storyboard.TargetProperty="(UIElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="EnabledBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}">
<ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/>
</Border>
<Border x:Name="DisabledOrReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed">
<TextBox x:Name="DisabledOrReadonlyContent" Background="Transparent" Foreground="{StaticResource PhoneDisabledBrush}" FontWeight="{TemplateBinding FontWeight}" FontStyle="{TemplateBinding FontStyle}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" IsReadOnly="True" SelectionForeground="{TemplateBinding SelectionForeground}" SelectionBackground="{TemplateBinding SelectionBackground}" TextAlignment="{TemplateBinding TextAlignment}" TextWrapping="{TemplateBinding TextWrapping}" Text="{TemplateBinding Text}" Template="{StaticResource PhoneDisabledTextBoxTemplate}"/>
</Border>
<TextBlock x:Name="WatermarkTextBlock" Style="{TemplateBinding WatermarkTextStyle}" Foreground="{TemplateBinding WatermarkTextForeground}" Text="{TemplateBinding WatermarkText}" IsHitTestVisible="False" Grid.ColumnSpan="2" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
用法:
<phone:PhoneApplicationPage
xmlns:controls="clr-namespace:System.Windows.Controls"
.....>
<controls:WatermarkTextBox WatermarkText="Your Watermark Text" />
答案 1 :(得分:2)
您似乎正在寻找水印文本框。您可以使用在文本框中显示文本的图像。这样,你就不会搞乱文本框的数据绑定。在此处阅读更多内容:http://msdn.microsoft.com/en-us/library/bb613590(v=vs.110).aspx
我将很快通过一个较旧的WP项目中的示例更新我的帖子。
编辑:
这是我使用的代码:
// location is a textbox
private void location_TextChanged(object sender, TextChangedEventArgs e)
{
if (location.Text == "")
{
ImageBrush watermark = new ImageBrush();
watermark.ImageSource =
new BitmapImage(new Uri(@"/Assets/Misc/watermark.png", UriKind.Relative));
watermark.AlignmentX = AlignmentX.Left;
watermark.Stretch = Stretch.None;
watermark.Opacity = .75;
location.Background = watermark;
}
else
{
location.Background = new SolidColorBrush(Colors.White);
}
}
private void location_LostFocus(object sender, RoutedEventArgs e)
{
location.Background.Opacity = .75;
}
这是(有点多余的)文本框XAML:
<TextBox x:Name="location" TextChanged="location_TextChanged" LostFocus="location_LostFocus">
<TextBox.Background>
<ImageBrush ImageSource="/Assets/Misc/watermark.png"
AlignmentX="Left" Stretch="None"
Opacity=".75"/>
</TextBox.Background>
</TextBox>
水印图像如下所示:
需要进行大量调整才能使图像正确,因为您必须考虑适当的背景颜色,字体大小等。
也许有更好的方法可以做到这一点,但我认为这是一个很好的起点。
<强>更新强>
使用Windows Phone 8.1,您只需使用TextBox的PlaceholderText
属性
<TextBox PlaceholderText="Enter search query"/>