文本框的文本预览 [英] TextPreview for Textbox

查看:16
本文介绍了文本框的文本预览的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

重新设计的问题以阐明我的需求:

我想在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆