【问题标题】:Issue with Dependency property & custom TextBox依赖属性和自定义文本框的问题
【发布时间】:2016-09-01 01:33:29
【问题描述】:

我想创建自定义文本框(其中将包含简单的水印/提示文本)并且我遇到了一些依赖属性的问题。 我的自定义类继承自 TextBox 类并包含两个文件 (.xaml .cs) C#代码文件很简单:

public partial class HintTextBox : TextBox
{
    public string HintText
    {
        get { return (string)GetValue(HintTextProperty); }
        set { SetValue(HintTextProperty, value); }
    }
    public static readonly DependencyProperty HintTextProperty =
        DependencyProperty.Register(
            "HintText",
            typeof(string),
            typeof(HintTextBox),
            new FrameworkPropertyMetadata(string.Empty));
}

.xaml 文件包含显示/隐藏水印的代码

<local:HintTextBox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:Ribes.Client.GUI"
                xmlns:sys="clr-namespace:System;assembly=mscorlib">
<local:HintTextBox.Style>
    <Style TargetType="{x:Type local:HintTextBox}">
        <Style.Resources>
            <VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
                <VisualBrush.Visual>
                    <Label Content="{Binding HintText, ElementName=local:HintTextBox}" Foreground="LightGray" />
                </VisualBrush.Visual>
            </VisualBrush>
        </Style.Resources>
        <Style.Triggers><!-- triggers changing content of control --></Style.Triggers>
    </Style>
</local:HintTextBox.Style>

我正在尝试简单地使用我的 HintTextBox:

<local:HintTextBox HintText="hint text"></local:HintTextBox>

而且它不起作用。 在线创建刹车点后:

SetValue(HintTextProperty, value);

代码永远无法到达。 TextBox 的继承属性(文本、背景)工作正常:

<local:HintTextBox Text="example text" Background="Yellow"></local:HintTextBox>

我们可以看到正确的黄色文本框,里面有“示例文本”。

有人知道我的 DP 有什么问题吗?

问候 NQ

【问题讨论】:

  • 如果我没记错的话,WPF 不使用 DP 的包装器属性,它使用带有 DP 的SetValue - 这就是没有达到断点的原因。我怀疑,绑定({Binding HintText, ElementName=local:HintTextBox})不正确(我的意思是ElementName

标签: c# wpf xaml


【解决方案1】:

您需要使用 Generic.xaml 来设置文本框的样式。为此,您需要在静态构造函数中覆盖 DefaultStyleKey。

HintTextBox.cs

public class HintTextBox : TextBox
{
    public static DependencyProperty HintTextProperty = DependencyProperty.Register("HintText", typeof(string), typeof(HintTextBox));

    public string HintText
    {
        get { return (string)GetValue(HintTextProperty); }
        set { SetValue(HintTextProperty, value); }
    }

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

Generic.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:Local="Ribes.Client.GUI">

    <!-- Describes how to style a HintTextBox -->
    <Style x:Key="{x:Type Local:HintTextBox}" BasedOn="{StaticResource {x:Type TextBox}}" TargetType="{x:Type Local:HintTextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Local:HintTextBox}">
                    <Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
                        <Grid x:Name="LayoutGrid">
                            <ScrollViewer x:Name="PART_ContentHost" Margin="2" />
                            <Label x:Name="HintText" Content="{Binding HintText, RelativeSource={RelativeSource TemplatedParent}}"
                                   FontStyle="Italic" Margin="2" Padding="2,0,0,0" />
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="HasText" Value="True">
                            <Setter Property="Visibility" TargetName="HintText" Value="Hidden" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

【讨论】:

    【解决方案2】:

    试试这个并设置一个断点:

    public string HintText
        {
            get { return (string)GetValue(HintTextProperty); }
            set { SetValue(HintTextProperty, value); }
        }
        public static readonly DependencyProperty HintTextProperty =
            DependencyProperty.Register(
                "HintText",
                typeof(string),
                typeof(HintTextBox),
                new FrameworkPropertyMetadata(null,FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,(sender,e)=>{
    
                    //Set Break Point Here
    
                });
    

    【讨论】:

    • 我认为这有点不幸......你给出了一个提示,如何监控 DP 的变化,但你没有描述,为什么你的解决方案比问题代码更好。而且我有一种感觉,“有人知道我的 DP 有什么问题吗?”这个问题实际上不仅仅针对 DP 存储价值,还针对 HintText 的视觉表示,即使没有明确要求。
    【解决方案3】:

    我现在无法访问 Visual Studio,但我认为您可能需要将 FrameworkPropertyMetadata 替换为 UIPropertyMetadata 到您的 DependencyProperty 中。

    【讨论】:

      猜你喜欢
      • 2011-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-16
      • 1970-01-01
      • 2012-05-30
      相关资源
      最近更新 更多