1

Possible Duplicate:
C# keyword usage virtual+override vs. new

I'm trying to hide my UserControl Content property in the following way:

public partial class Tile : UserControl
{
    public new object Content
    {
        get { ... }
        set { ... }
    }
}

But when I set the Content of my UserControl it does not do anything (if I set a breakpoint it is never reached):

<my:Tile Content="The content"/>

or

<my:Tile>The content</my:Tile>

Why? How can I solve this problem?

Community
  • 1
  • 1
Nick
  • 10,309
  • 21
  • 97
  • 201
  • 2
    What do you mean by, "it does not change anything"? – Kirk Woll Oct 20 '12 at 20:48
  • @KirkWoll If i set a breakpoint it is never reached... – Nick Oct 20 '12 at 20:55
  • 1
    @ErikPhilips Content property is not virtual... Do you know wpf? – Nick Oct 20 '12 at 20:56
  • If you read the answer in the link, then you'd understand why this is happening. In short, a `new` property does not remove, hide or get rid of the base types property of the same name. In your case when any method uses your `Tile` class as the type `UserControl` it will be access the property `UserControl.Content`. This is basic understanding of how C# works and nothing to do with a framework that uses C#. – Erik Philips Oct 20 '12 at 21:03
  • 2
    @Erik WPF doesn't use his class as the type UserControl, so you are wrong. It uses DependencyObject.GetValue/SetValue, so the problem is that he isn't hiding the dependency property. – Mike Marynowski Oct 20 '12 at 21:21
  • The new keyword in this context does only **one** thing. It stops the compiler from telling you are doing it wrong. With heavy odds that this didn't stop you from doing it wrong. The second hint is that you didn't use, or could use, the override keyword. So you didn't override anything. The original method is still there, un-overridden. – Hans Passant Oct 20 '12 at 23:42
  • @MikeMarynowski so guess what, [UserControl](http://msdn.microsoft.com/en-us/library/system.windows.controls.usercontrol.aspx) derives from DependecyObject. Therefore what I said for any base object before Tile is true. If WPF uses Dependency object, his new Object content will still be ignored. It is a fundamental rule governing how the C# compiler works with any derived object. – Erik Philips Oct 21 '12 at 03:47
  • His new object content will NOT be ignored, because WPF doesn't do this: ((UserControl)yourTileObject).Content = "blah"; Rather, it does this: ((DependencyObject)yourTileObject).SetValue(Tile.ContentProperty, "blah"); After dynamically looking up "ContentProperty", starting from the top off the class hierarchy, not the bottom. – Mike Marynowski Oct 22 '12 at 15:14
  • You can try it yourself really quickly. I just created a UserControl, added a new content property like I described below, threw it into a window and set its Content property to "test" in XAML. You can see that UserControl.Content stays at its default value, and Tile.Content gets set to "test". – Mike Marynowski Oct 22 '12 at 15:31
  • 1
    This is not duplicate as wpf introduces `DependencyProperty` and answer is not really about `new` keyword. – Sinatr Nov 10 '16 at 09:20

2 Answers2

1

The problem is that you aren't hiding the actual DependencyProperty, only the get/set accessor which WPF may or may not always use to set the value of the DP. WPF has optimizations that directly call DependencyObject.GetValue/SetValue instead.

Create a dependency property on your object with the name "Content" instead and then new up the get/set accessors and what you are doing should work.

public static readonly new DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof(object), typeof(Tile));

public new object Content
{
    get { return this.GetValue(ContentProperty); }
    set { this.SetValue(ContentProperty, value); }
}

I'm not sure why you would want to do this though, instead of just using the content property that is already there. It would seem to me that you are fighting the framework here and there's an easier way to do what you want.

Mike Marynowski
  • 3,156
  • 22
  • 32
  • Don't worry about what i have to do thanks. can you show me some piece of code? – Nick Oct 20 '12 at 21:03
  • As the answer below indicates, there are better ways to use the existing content property. But if you really want to hide the base property, I'll update the answer. – Mike Marynowski Oct 20 '12 at 21:14
  • Given that you are asking me to show you some code that registers a dependency property, which is really the very basics of WPF, I'm guessing you are pretty new at WPF and I think you should reconsider hiding your intent because we can probably suggest a better way of doing it. – Mike Marynowski Oct 20 '12 at 21:19
0

If you'd like to plug-in your own functionality to the Content property, what you're probably looking for is DependencyProperty.OverrideMetadata(). This way you can add your own property changed handler in your derived class. It would look something like this:

static Tile()
{
    ContentProperty.OverrideMetadata(typeof(Tile), new PropertyMetadata(null, OnContentChanged));
}

private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    // Your logic goes here.
}

EDIT

Just had a look, and WPF already took care of this for you. You can simply override OnContentChanged:

protected override void OnContentChanged(object oldContent, object newContent)
{
    base.OnContentChanged(oldContent, newContent);

    // Your logic goes here.
}
Adi Lester
  • 24,731
  • 12
  • 95
  • 110