How to apply CueBanner for a TextBox in xaml

核能气质少年 提交于 2019-12-11 05:46:58

问题


I want to have a TextBox with CueBanner but it still does not work. What have I made wrong? I think the problem is that I am using {RelativeSource TemplatedParent} in Resources. How can I do that without putting in Resources?

My xaml code:

<Style TargetType="{x:Type TextBox}">
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
    <Setter Property="MinWidth" Value="120" />
    <Setter Property="MinHeight" Value="20" />
    <Setter Property="AllowDrop" Value="true" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <ControlTemplate.Resources>
                    <VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
                        <VisualBrush.Visual>
                            <Label Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Tag}"
                                       Foreground="LightGray" />
                        </VisualBrush.Visual>
                    </VisualBrush>
                </ControlTemplate.Resources>

                <Border x:Name="Border" CornerRadius="0" Padding="2" BorderThickness="1" BorderBrush="Black">
                    <ScrollViewer Margin="0" x:Name="PART_ContentHost" />
                </Border>

                <ControlTemplate.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="LightGreen"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Thanks for any advice.

EDIT

My problem is solved and here is my final solution:

<Style TargetType="{x:Type TextBox}">
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
    <Setter Property="BorderBrush" Value="Gray"/>
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="AllowDrop" Value="true"/>
    <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
    <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="OverridesDefaultStyle" Value="True" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Border x:Name="Border" CornerRadius="0" Padding="2" 
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="1"
                        Background="{TemplateBinding Background}">
                    <Grid>
                        <ScrollViewer Margin="0" x:Name="PART_ContentHost" />
                        <TextBlock x:Name="Watermark"
                               Text="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}"
                               Foreground="LightGray" Margin="5,0" Visibility="Collapsed"/>
                    </Grid>
                </Border>

                <ControlTemplate.Triggers>
                    <Trigger Property="Text" Value="{x:Static sys:String.Empty}">
                        <Setter Property="Visibility" TargetName="Watermark" Value="Visible" />
                    </Trigger>
                    <Trigger Property="Text" Value="{x:Null}">
                        <Setter Property="Visibility" TargetName="Watermark" Value="Visible" />
                    </Trigger>
                    <Trigger Property="IsMouseCaptured" Value="True">
                        <Setter Property="Visibility" TargetName="Watermark" Value="Collapsed"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Opacity" TargetName="Border" Value="0.56"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Cursor" Value="IBeam" />
        </Trigger>
    </Style.Triggers>
</Style>

回答1:


So I wasn't sure what you meant by "CueBanner" at first until I realized it was just synonymous with "Watermark" pretty much. So as a quick example, this would be a quick and easy alternative (since at first glance I don't understand what made that VisualBrush stuff necessary you had in there) made a bit more clean and re-usable though I'm sure you'll want to change the colors I used just for the example. You might also look into something like the Extended Toolkit for some more of this stuff built in, but theirs for example does watermarks differently than this example.

Anyhow, concept example Style template (noticed added the mscorlib namespace in case you don't have it in your res. dict. already for sys:String;

<SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/>
<SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/>

<Style x:Key="CWWatermarkTextBoxStyle" TargetType="{x:Type TextBox}" 
       xmlns:sys="clr-namespace:System;assembly=mscorlib">
   <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
   <Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
   <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
   <Setter Property="BorderThickness" Value="1"/>
   <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
   <Setter Property="HorizontalContentAlignment" Value="Left"/>
   <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
   <Setter Property="AllowDrop" Value="true"/>
   <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
   <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type TextBox}">
            <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
               <Grid>
                  <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                  <TextBlock x:Name="GenericWatermark"
                             Text="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}"
                             Foreground="Red" Margin="5,0" Visibility="Collapsed"/>
               </Grid>
            </Border>
         <ControlTemplate.Triggers>
            <Trigger Property="Text" Value="{x:Static sys:String.Empty}">
               <Setter Property="Visibility" TargetName="GenericWatermark" Value="Visible" />
               <Setter Property="Background" Value="Yellow" />
            </Trigger>
            <Trigger Property="IsEnabled" Value="false">
               <Setter Property="Opacity" TargetName="border" Value="0.56"/>
            </Trigger>
            <Trigger Property="IsMouseOver" Value="true">
               <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
            </Trigger>
            <Trigger Property="IsKeyboardFocused" Value="true">
               <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
               <Setter Property="Visibility" TargetName="GenericWatermark" Value="Collapsed"/>
            </Trigger>
         </ControlTemplate.Triggers>
      </ControlTemplate>
   </Setter.Value>
   </Setter>
   <Style.Triggers>
      <MultiTrigger>
         <MultiTrigger.Conditions>
            <Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
            <Condition Property="IsSelectionActive" Value="false"/>
         </MultiTrigger.Conditions>
         <Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
      </MultiTrigger>
   </Style.Triggers>
</Style>

....and usage at the instance example;

<TextBox Tag="HEY LOOK! I'M A TEXTBOX WITH A WATERMARK! WEEEE! :)"
         Style="{StaticResource CWWatermarkTextBoxStyle}"/>

Voila, a quick and simple wpf xaml textbox with watermark. Hope this helps, cheers.



来源:https://stackoverflow.com/questions/39213504/how-to-apply-cuebanner-for-a-textbox-in-xaml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!