文本框的文本预览 [英] TextPreview for Textbox
问题描述
重新设计的问题以阐明我的需求:
我想在 Textboxes
为空时向它们添加预览文本,就像你们中的一些人可能从 Xamarin
知道的那样.
我在
由于这运行良好,我想将它应用到该 Window
中的每个 TextBox
.所以我的方法是改变这一行:<Label Content="Test" Foreground="LightGray"/>
我想也许将其更改为 <Label Content="Test" Foreground="LightGray"/>
可以解决问题,但它不起作用.
我猜这与 Tag
属性和 Type
(对象而不是字符串)
有关.
由于第一种方法效果很好,我真的不明白为什么我需要一个自定义控件......
所以我当时尝试的是:
<Style TargetType="TextBox"><样式.资源><VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None"><VisualBrush.Visual><Label Content="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" Foreground="LightGray"/></VisualBrush.Visual></VisualBrush></Style.Resources><Style.Triggers><Trigger Property="Text" Value="{x:Static sys:String.Empty}"><Setter Property="Background" Value="{StaticResource CueBannerBrush}"/></触发器><Trigger Property="Text" Value="{x:Null}"><Setter Property="Background" Value="{StaticResource CueBannerBrush}"/></触发器><Trigger Property="IsKeyboardFocused" Value="True"><Setter Property="Background" Value="White"/></触发器></Style.Triggers></风格></Window.Resources>
我错过了什么 - 为什么这不起作用?
对于可重用的文本框,您需要创建一个自定义控件.同样对于绑定不适用于视觉画笔,因此您需要一些临时对象来存储值.参考我下面的代码.
<窗口.资源><local:Temp x:Key="temp" Value="{Binding ElementName=Hostname, Path=Watermark}"/><Style TargetType="{x:Type local:WatermarkTextBox}" BasedOn="{StaticResource {x:Type TextBox}}"><样式.资源><VisualBrush x:Key="WatermarkBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None"><VisualBrush.Visual><TextBlock Text="{Binding Source={StaticResource temp}, Path=Value}" FontFamily="Segoe UI" FontSize="20" Foreground="LightGray" Padding="5"/></VisualBrush.Visual></VisualBrush></Style.Resources><Style.Triggers><Trigger Property="Text" Value="{x:Static sys:String.Empty}"><Setter Property="Background" Value="{StaticResource WatermarkBrush}"/></触发器><Trigger Property="Text" Value="{x:Null}"><Setter Property="Background" Value="{StaticResource WatermarkBrush}"/></触发器><Trigger Property="IsKeyboardFocused" Value="True"><Setter Property="Background" Value="White"/></触发器></Style.Triggers></风格></Window.Resources><网格><local:WatermarkTextBox x:Name="Hostname" Height="40" FontFamily="Segoe UI" FontSize="20" VerticalContentAlignment="Center" Watermark="Hello, world." ></local:WatermarkTextBox></网格></窗口>公共类 Temp : Freezable{//依赖属性public static readonly DependencyProperty ValueProperty =DependencyProperty.Register("Value", typeof(string),typeof(Temp), new FrameworkPropertyMetadata(string.Empty));//.NET 属性包装器公共字符串值{得到{返回(字符串)GetValue(ValueProperty);}设置 { SetValue(ValueProperty, value);}}受保护的覆盖 System.Windows.Freezable CreateInstanceCore(){返回新的温度();}}公共类 WatermarkTextBox : TextBox{静态 WatermarkTextBox(){DefaultStyleKeyProperty.OverrideMetadata(typeof(WatermarkTextBox), new FrameworkPropertyMetadata(typeof(WatermarkTextBox)));}public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(string), typeof(WatermarkTextBox));公共字符串水印{获取{返回(字符串)GetValue(WatermarkProperty);}set { SetValue(WatermarkProperty, value);}}}
Reworked Question to clarify my needs:
I want to add a preview Text to Textboxes
when they're empty, just like some of you may know it from Xamarin
.
I have found this answer on SO.
This is the Style
from the Answer I linked above.
<TextBlock Grid.Row="5"
Grid.Column="1"
VerticalAlignment="Center"
Text="Username:">
</TextBlock>
<TextBox Grid.Row="5"
Grid.Column="3">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="Test" Foreground="LightGray" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
I get the following result:
Since this is working nicely I want to apply it to every TextBox
in that Window
.
So my approach was to change this line:
<Label Content="Test" Foreground="LightGray" />
I thought maybe changing it to <Label Content="Test" Foreground="LightGray" />
would do the trick, but it is not working.
I guess it's something with the Tag
Property and the Type
of it (object instead of string)
.
Since the first approach is working like charm I don't really see why I should need a custom control for that...
So what I tried then is this:
<Window.Resources>
<Style TargetType="TextBox">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" Foreground="LightGray" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
What am I missing - why isn't that working ?
For the reusable textbox, you need to create a custom control. Also for binding doesnot work well with visual brush, so you need some temp object to store the value. Refer my below code.
<Window x:Class="ChkList_Learning.Window4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ChkList_Learning"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="Window4" Height="300" Width="300">
<Window.Resources>
<local:Temp x:Key="temp" Value="{Binding ElementName=Hostname, Path=Watermark}"/>
<Style TargetType="{x:Type local:WatermarkTextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Style.Resources>
<VisualBrush x:Key="WatermarkBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<TextBlock Text="{Binding Source={StaticResource temp}, Path=Value}" FontFamily="Segoe UI" FontSize="20" Foreground="LightGray" Padding="5" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource WatermarkBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource WatermarkBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<local:WatermarkTextBox x:Name="Hostname" Height="40" FontFamily="Segoe UI" FontSize="20" VerticalContentAlignment="Center" Watermark="Hello, world.">
</local:WatermarkTextBox>
</Grid>
</Window>
public class Temp : Freezable
{
// Dependency Property
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(string),
typeof(Temp), new FrameworkPropertyMetadata(string.Empty));
// .NET Property wrapper
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
protected override System.Windows.Freezable CreateInstanceCore()
{
return new Temp();
}
}
public class WatermarkTextBox : TextBox
{
static WatermarkTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(WatermarkTextBox), new FrameworkPropertyMetadata(typeof(WatermarkTextBox)));
}
public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(string), typeof(WatermarkTextBox));
public string Watermark
{
get { return (string)GetValue(WatermarkProperty); }
set { SetValue(WatermarkProperty, value); }
}
}
这篇关于文本框的文本预览的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!