自定义控件未呈现

发布于 2024-12-06 05:16:57 字数 6630 浏览 1 评论 0原文

下面的控件背后的想法是能够在没有任何文本时在文本框内显示标签。为此,我只使用了一个类似的工作控件,即 SearchTextBox,但有太多功能无法满足我的需要。

我怀疑下面样式的控制模板,但我没有发现它有任何明显的问题。不过,我很容易会错过一些对于有更多经验的人来说显而易见的东西。

我该如何修复或排除此问题?

干杯,
Berryl

代码

/// <summary>Light weight version of a <see cref="SearchTextBox"/></summary>
public class LabelTextBox : TextBox
{

    #region Dependency Properties

    #region Label Text

    /// <summary>Sets the 'watermark' text that acts as a label, identifying what this will search for.</summary>
    public static readonly DependencyProperty LabelTextProperty =
        DependencyProperty.Register("LabelText", 
            typeof (string), typeof (LabelTextBox), new PropertyMetadata("Search"));

    public string LabelText
    {
        get { return (string) GetValue(LabelTextProperty); }
        set { SetValue(LabelTextProperty, value); }
    }

    /// <summary>Brush for the label text.</summary>
    public static readonly DependencyProperty LabelTextColorProperty =
        DependencyProperty.Register("LabelTextColor", typeof (Brush), typeof (LabelTextBox));

    public Brush LabelTextColor
    {
        get { return (Brush)GetValue(LabelTextColorProperty); }
        set { SetValue(LabelTextColorProperty, value); }
    }

    #endregion

    #region Has Text

    private static readonly DependencyPropertyKey HasTextPropertyKey =
        DependencyProperty.RegisterReadOnly("HasText", 
            typeof (bool), typeof (LabelTextBox), new PropertyMetadata());

    /// <summary>True if the user has typed in text.</summary>
    public static readonly DependencyProperty HasTextProperty = HasTextPropertyKey.DependencyProperty;

    public bool HasText
    {
        get { return (bool)GetValue(HasTextProperty); }
        private set { SetValue(HasTextPropertyKey, value); }
    }

    #endregion

    #endregion

    #region Construction

    static LabelTextBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof (LabelTextBox), new FrameworkPropertyMetadata(typeof (LabelTextBox)));
    }

    #endregion

    #region Event Handlers

    protected override void OnTextChanged(TextChangedEventArgs e)
    {
        base.OnTextChanged(e);

        HasText = Text.Length != 0;
    }

    #endregion

}

风格

<Style x:Key="{x:Type cc:LabelTextBox}" TargetType="{x:Type cc:LabelTextBox}">
    <Setter Property="Background" Value="{StaticResource SearchTextBox_Background}" />
    <Setter Property="BorderBrush" Value="{StaticResource SearchTextBox_Border}" />
    <Setter Property="Foreground" Value="{StaticResource SearchTextBox_Foreground}" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="LabelText" Value="Search" />
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="LabelTextColor" Value="{StaticResource SearchTextBox_LabelTextColor}" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type cc:LabelTextBox}">

                <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" Padding="2" 
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Background="{TemplateBinding Background}"
                        >

                    <Grid x:Name="LayoutGrid">

                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}" />
                        </Grid.ColumnDefinitions>

                        <ScrollViewer x:Name="PART_ContentHost" Grid.Column="0" />

                        <Label x:Name="LabelText" Grid.Column="0" 
                               Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LabelTextColor}" 
                               Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LabelText}" 
                               Padding="2,0,0,0" FontStyle="Italic" 
                               />

                    </Grid>

                </Border>

                <ControlTemplate.Triggers>

                    <!--input triggers (mouse over && keyboard focused-->
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="BorderBrush" Value="{StaticResource SearchTextBox_BorderMouseOver}" />
                    </Trigger>
                    <Trigger Property="IsKeyboardFocusWithin" Value="True">
                        <Setter Property="BorderBrush" Value="{StaticResource SearchTextBox_BorderMouseOver}" />
                    </Trigger>

                    <!--Once the user has typed in search text-->

                    <Trigger Property="HasText" Value="True">
                        <!--Hide the label text-->
                        <Setter Property="Visibility" TargetName="LabelText" Value="Hidden" />
                    </Trigger>

                </ControlTemplate.Triggers>

            </ControlTemplate>
        </Setter.Value>

    </Setter>

    <!--
    Error display
    -->
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel LastChildFill="True">
                    <TextBlock DockPanel.Dock="Right" Text=" *" 
                               Foreground="Red" 
                               FontWeight="Bold" FontSize="16" 
                               ToolTip="{Binding ElementName=placeholder, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}"/>
                    <Border BorderBrush="Red"  BorderThickness="1">
                        <AdornedElementPlaceholder Name="placeholder"></AdornedElementPlaceholder>
                    </Border>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="True">
            <Setter Property="Background" Value="LightYellow"/>
        </Trigger>
    </Style.Triggers>


</Style>

The idea behind the control below is to be able to show a Label inside of a TextBox when there isn't any text. To do this, I just took a working control that is similar, a SearchTextBox, but has too much going on for what I need here.

I suspect the control template in the style below but I don't see any thing obviously wrong with it. I could easily be missing something that is obvious to someone with more experience though.

How do I fix or trouble shoot this?

Cheers,
Berryl

Code

/// <summary>Light weight version of a <see cref="SearchTextBox"/></summary>
public class LabelTextBox : TextBox
{

    #region Dependency Properties

    #region Label Text

    /// <summary>Sets the 'watermark' text that acts as a label, identifying what this will search for.</summary>
    public static readonly DependencyProperty LabelTextProperty =
        DependencyProperty.Register("LabelText", 
            typeof (string), typeof (LabelTextBox), new PropertyMetadata("Search"));

    public string LabelText
    {
        get { return (string) GetValue(LabelTextProperty); }
        set { SetValue(LabelTextProperty, value); }
    }

    /// <summary>Brush for the label text.</summary>
    public static readonly DependencyProperty LabelTextColorProperty =
        DependencyProperty.Register("LabelTextColor", typeof (Brush), typeof (LabelTextBox));

    public Brush LabelTextColor
    {
        get { return (Brush)GetValue(LabelTextColorProperty); }
        set { SetValue(LabelTextColorProperty, value); }
    }

    #endregion

    #region Has Text

    private static readonly DependencyPropertyKey HasTextPropertyKey =
        DependencyProperty.RegisterReadOnly("HasText", 
            typeof (bool), typeof (LabelTextBox), new PropertyMetadata());

    /// <summary>True if the user has typed in text.</summary>
    public static readonly DependencyProperty HasTextProperty = HasTextPropertyKey.DependencyProperty;

    public bool HasText
    {
        get { return (bool)GetValue(HasTextProperty); }
        private set { SetValue(HasTextPropertyKey, value); }
    }

    #endregion

    #endregion

    #region Construction

    static LabelTextBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof (LabelTextBox), new FrameworkPropertyMetadata(typeof (LabelTextBox)));
    }

    #endregion

    #region Event Handlers

    protected override void OnTextChanged(TextChangedEventArgs e)
    {
        base.OnTextChanged(e);

        HasText = Text.Length != 0;
    }

    #endregion

}

Style

<Style x:Key="{x:Type cc:LabelTextBox}" TargetType="{x:Type cc:LabelTextBox}">
    <Setter Property="Background" Value="{StaticResource SearchTextBox_Background}" />
    <Setter Property="BorderBrush" Value="{StaticResource SearchTextBox_Border}" />
    <Setter Property="Foreground" Value="{StaticResource SearchTextBox_Foreground}" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="LabelText" Value="Search" />
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="LabelTextColor" Value="{StaticResource SearchTextBox_LabelTextColor}" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type cc:LabelTextBox}">

                <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" Padding="2" 
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Background="{TemplateBinding Background}"
                        >

                    <Grid x:Name="LayoutGrid">

                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}" />
                        </Grid.ColumnDefinitions>

                        <ScrollViewer x:Name="PART_ContentHost" Grid.Column="0" />

                        <Label x:Name="LabelText" Grid.Column="0" 
                               Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LabelTextColor}" 
                               Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LabelText}" 
                               Padding="2,0,0,0" FontStyle="Italic" 
                               />

                    </Grid>

                </Border>

                <ControlTemplate.Triggers>

                    <!--input triggers (mouse over && keyboard focused-->
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="BorderBrush" Value="{StaticResource SearchTextBox_BorderMouseOver}" />
                    </Trigger>
                    <Trigger Property="IsKeyboardFocusWithin" Value="True">
                        <Setter Property="BorderBrush" Value="{StaticResource SearchTextBox_BorderMouseOver}" />
                    </Trigger>

                    <!--Once the user has typed in search text-->

                    <Trigger Property="HasText" Value="True">
                        <!--Hide the label text-->
                        <Setter Property="Visibility" TargetName="LabelText" Value="Hidden" />
                    </Trigger>

                </ControlTemplate.Triggers>

            </ControlTemplate>
        </Setter.Value>

    </Setter>

    <!--
    Error display
    -->
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel LastChildFill="True">
                    <TextBlock DockPanel.Dock="Right" Text=" *" 
                               Foreground="Red" 
                               FontWeight="Bold" FontSize="16" 
                               ToolTip="{Binding ElementName=placeholder, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}"/>
                    <Border BorderBrush="Red"  BorderThickness="1">
                        <AdornedElementPlaceholder Name="placeholder"></AdornedElementPlaceholder>
                    </Border>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="True">
            <Setter Property="Background" Value="LightYellow"/>
        </Trigger>
    </Style.Triggers>


</Style>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鹤舞 2024-12-13 05:16:57

这似乎有效。我所做的只是将您的代码复制到一个名为 LabelTextBox 的类中,并将您的 Style 复制到 Themes< 的 Generic.xaml 资源字典中。 /code> 文件夹放置在项目根目录(我将画笔颜色更改为 LightBlue、LightGray、Blue 等)

This seems to be working. All I did was to copy your code in a class called LabelTextBox and your Style in a Generic.xaml resource dictionary in Themes folder placed at project root (I changed the brush colors to LightBlue, LightGray, Blue etc.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文