C# 为什么用propdp代码段编写的依赖项属性不起作用?

C# 为什么用propdp代码段编写的依赖项属性不起作用?,c#,wpf,dependency-properties,C#,Wpf,Dependency Properties,我有一个带有简单依赖属性的类,它是在VisualStudio中的propdp代码片段的帮助下编写的。我从TextBox派生了这个类,并给了它一个PrePend属性,我希望它是一个依赖属性。我希望这样,如果用户将PrePend设置为“Hello”,并将Text设置为“World”,则Textgetter将返回“Hello World”。我的问题是代码似乎忽略了我的PrePend依赖属性 我的班级在这里: internal class MyTextBox : TextBox { public

我有一个带有简单依赖属性的类,它是在VisualStudio中的
propdp
代码片段的帮助下编写的。我从
TextBox
派生了这个类,并给了它一个
PrePend
属性,我希望它是一个依赖属性。我希望这样,如果用户将
PrePend
设置为“Hello”,并将
Text
设置为“World”,则
Text
getter将返回“Hello World”。我的问题是代码似乎忽略了我的
PrePend
依赖属性

我的班级在这里:

internal class MyTextBox : TextBox
{
    public new string Text
    {
        get { return this.PrePend + base.Text; }
        set { base.Text = value; }
    }

    public string PrePend
    {
        get { return (string)GetValue(PrePendProperty); }
        set { SetValue(PrePendProperty, value); }
    }

    // Using a DependencyProperty as the backing store for PrePend.  
    //   This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PrePendProperty =
        DependencyProperty.Register("PrePend", typeof(string), 
          typeof(MyTextBox), new PropertyMetadata(""));
}
我通过使用
propdp
代码片段获得了这段代码。我只添加了
文本设置器

我的
XAML
代码就是这样:

<local:MyTextBox PrePend="Hello " Text="World" />

当我运行代码时,屏幕显示“World”。我在
Text
getter和setter以及
PrePend
getter和setter中放置了断点,但代码从未在那里中断

这个简单的例子我做错了什么?我是否应该使用
propdp
代码片段来执行此操作?我不太了解依赖属性。

这是“非法”的,因为WPF总是直接访问依赖属性,该属性只不过是一个包装器。这就是为什么您应该永远不要更改或在属性中放置逻辑,它们永远不会被wpf内部使用

public new string Text // Bad pie!
{
    get { return this.PrePend + base.Text; } // Bad pie!
    set { base.Text = value; }
}
如果要在属性更改时执行某些操作,请在声明依赖项属性时添加OnPrePendPropertyChanged处理程序

即:

您还可以将处理程序添加到现有的依赖项属性中,如文本属性。这必须在类的静态构造函数中完成

在可能的情况下,我个人更愿意创建一个用于扩展控件功能的应用程序。

在当前的情况下(<强>我怀疑你正在试验?<强> >),我会考虑使用一个STD文本框,然后将文本属性绑定到VM上的一个道具上,并在绑定中使用你的魔法,和/或在绑定中使用A。 希望能有帮助

干杯


Stian

由于数据绑定/动画更新而更改值时,WPF不使用setter

如果要响应依赖项属性中的更改,可以执行以下两种操作之一:

  • 将PropertyChanged处理程序添加到寄存器调用中的PropertyMetaData

  • 不要在控件中处理更改,而是在ViewModel中处理更改


  • 触发PropertyChanged事件?我不确定覆盖您的
    文本
    值是否安全<
    TextBox
    中的code>Text
    也是一个依赖属性。在不更改属性的情况下重新实现它听起来不是一个好主意。我应该将PropertyChanged事件放在哪里?在文本设置器中?我对base.Text setter的调用不会触发该事件吗?还是前置设置器?在这种情况下,对SetValue的调用不会触发该事件吗?除此之外,如果需要的话,propdp代码段不会包含对PropertyChanged的调用吗?我删除了文本设置程序,将XAML更改为
    ,并更改了前置设置程序,以便它调用
    设置值(TextProperty,value)。这样,我希望出现前置值“Hello”。相反,我什么也得不到。即使我正在通过
    Setvalue(…)
    设置文本,也不会设置文本。当我在我的前置设置器中放置断点并运行程序时,breapoint永远不会跳闸:我的前置设置器根本不会被调用。我认为这里还有其他问题。@user2023861除非您更改textbox的控件模板以显示PrePend属性而不是Text属性,否则这将不起作用。Mate在viewmodel中执行此操作,或者改用行为!:)行为很简单也很好。我最终选择了你的第一个选择。谢谢我发现VisualStudio附带的propdp片段似乎不起作用,这很有趣。也许我理解错了。我必须创建自己的代码段,其中包含PropertyChanged处理程序,因为我永远也记不起该样板代码。他们只是没有在代码段中添加处理程序。通常,大多数依赖项属性不会处理此事件。小心,如果应用程序的实现不好,并且属性经常更改,那么它可能会减慢应用程序的速度
    public static readonly DependencyProperty PrePendProperty = DependencyProperty.Register("PrePend", typeof(string), typeof(MyTextBox), new PropertyMetadata(String.Empty, OnPrePendPropertyChanged ));
    
    private static void OnPrePendPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
       var ctl = sender as MyTextBox ;
       ctl.OnPrePendChanged();
    }
    
    protected virtual void OnPrePendChanged()
    {
       // do your magic here
    }
    
    static MyTextBox 
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(typeof(MyTextBox)));
        TextBox.TextProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnTextPropertyChanged)));
    }
    
    // Add your handlers as above