views:

332

answers:

2

Here's the situation: I have a custom TextBox control that contains multiple other TextBox controls. I need to turn IsTabStop off in the parent control, but I still want to expose a new IsTabStop property, which the sub-textboxes are template-bound to. I wrote the following code:

using System.Windows.Controls;

public class CustomTextBox : Control {
 public CustomTextBox() {
     base.IsTabStop = false;
 }

 [Description( "Gets or sets whether a control is included in tab navigation." )]
 [Category( "Common Properties" )]
 public new bool IsTabStop
 {
     get { return (bool)GetValue( IsTabStopProperty ); }
     set { SetValue( IsTabStopProperty, value ); }
 }

 public new static readonly DependencyProperty IsTabStopProperty = DependencyProperty.Register(
     "IsTabStop",
     typeof( bool ),
     typeof( CustomTextBox ),
     new PropertyMetadata( true ) );
}

But that results in strange behavior. When IsTabStop is not specified for instances of the custom controls, it acts like IsTabStop is false, even though the default is true. If IsTabStop is explicitly marked true, though, the base class's IsTabStop is set to true. Also, if I rename "IsTabStop" and all related text (including the bindings) to "IsTabStopx", thus not hiding the base member, it works as desired. Shouldn't a hidden member act the same as a brand new definition? Could something somewhere be reading the base class's IsTabStop?

What's going on?

+2  A: 

The DependencyProperty system operates independently of the C# property getters and setters which are provided as a convienience to the programmer.

WPF/Silverlight will read the Control.IsTabStopProperty directly and will not use the CustomTextBox.IsTabStop property or the CustomTextBox.IsTabStopProperty DependencyProperty.

Doug Ferguson
Is there no way around this behavior? I thought that by defining a "new" static dependency property and registering it, it would behave like other object-oriented facilities and hide the parent class's member. This worked for me in another instance, when I changed the type of a new dependency property, but kept its name.
Dov
A: 

I suspect you need to review what actually happens when you "hide" a member of a parent type. Any code that uses the parent type will not see your new definition, it will continue to use the existing member defined by the parent. Only code that is written against your new derived type will start using the new definition.

In this case when a reference to your custom control is held as a Control type any access to IsTabStop will return the implementation in Control. Only when code knows its working against the type CustomTextBox will it use your custom definition.

AnthonyWJones
But it's defined in the XAML as a CustomTextBox, not a Control. What are you saying might not see the new type?
Dov