【问题标题】:TextPreview for Textbox文本框的文本预览
【发布时间】:2016-10-26 00:50:18
【问题描述】:

重新编写问题以阐明我的需求:

我想在 Textboxes 为空时添加预览文本,就像你们中的一些人可能从 Xamarin 知道的一样。

我在SO 上找到了这个答案。

这是我上面链接的答案中的Style

<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>

我得到以下结果:

由于它运行良好,我想将它应用到该Window 中的每个TextBox。 所以我的方法是改变这一行: &lt;Label Content="Test" Foreground="LightGray" /&gt;

我认为也许将其更改为 &lt;Label Content="Test" Foreground="LightGray" /&gt; 可以解决问题,但它不起作用。

我猜这与 Tag 属性和它的 Type (object instead of string) 有关。

由于第一种方法很有效,我真的不明白为什么我需要一个自定义控件...

所以我当时尝试的是这样的:

 <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>

我错过了什么 - 为什么这不起作用?

【问题讨论】:

  • 如果你想使用这种特定的方式,只需给样式模板一个 x:Key 名称并将其放在资源字典中,然后全局设置或在实例中使用它,如 &lt;TextBox Style="{StaticResource StyleTemplateKeyName}"/&gt;
  • Ayyappan Subramanian 表示 VisualBrush 中的绑定需要一些帮助才能找到 DataContext。他使用他的 Temp 类(例如BindingProxy)解决了这个问题。
  • @Funk 所以这意味着没有自定义控件是不可能的? - 另请注意,如果有没有 VisualBrush 的完全不同的解决方案,我想听听。
  • “为什么这不起作用?”因为RelativeSource 绑定会将标签的标签放入标签内容中,所以您需要标签中的文本框标签。但是你不会得到它,因为标签上方没有 VisualTree。

标签: c# wpf xaml binding textbox


【解决方案1】:

对于可重用的文本框,您需要创建一个自定义控件。对于绑定也不能很好地与视觉画笔一起使用,因此您需要一些临时对象来存储该值。参考我下面的代码。

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

【讨论】:

  • 我修改了我的问题你能再看看吗^^
猜你喜欢
  • 2012-06-25
  • 1970-01-01
  • 2013-05-22
  • 1970-01-01
  • 2013-04-12
  • 1970-01-01
  • 2011-09-26
  • 2015-09-29
  • 1970-01-01
相关资源
最近更新 更多