Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
702 views
in Technique[技术] by (71.8m points)

c# - TextPreview for Textbox

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:

enter image description here

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 ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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); }
        }
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...