Metadata overriding ignored?
I have made a very simple test project:
MainWindow.xaml:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Test"
Title="MainWindow" Height="350" Width="525" VerticalAlignment="Center" HorizontalAlignment="Center">
<StackPanel x:Name="mainPanel" />
</Window>
MainWindow.xaml.cs:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Test
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MyTextBox myTextBox = new MyTextBox("some text here");
mainPanel.Children.Add(myTextBox);
}
}
}
MyTextBox.cs:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Test
{开发者_开发百科
class MyTextBox : TextBox
{
static MyTextBox()
{
MyTextBox.BackgroundProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(Brushes.Red));
}
public MyTextBox(string Content)
{
Text = Content;
}
}
}
this, in order to test the metaData Overriding function.
now the trouble is: this does not work as I expected it to...
indeed, the MyTextBox's background is white, and not Red.
I investigated and tried this as constructor for my custom class:
public MyTextBox(string Content)
{
Text = Content;
Background = Brushes.Blue;
ClearValue(BackgroundProperty);
}
now here is what I found out when I debugged:
in the main class:
MyTextBox myTextBox = new MyTextBox("some text here");
we go into the custom class's static constructor, then in the instance's constructor:
Text = Content;
>> Background = Red
Background = Brushes.Blue;
>> Background = Blue
ClearValue(BackgroundProperty);
>> Background = Red again (as expected)
we go back to the main class:
mainPanel.Children.Add(myTextBox);
... and right after this line of code, myTextBox.Background
is White.
Question: Why?
why is this set to white when I add it to the mainPanel??? I cannot find any logical explanation to this...
furthermore, if I add some more code where I do something like: myTextBox.Background = Brushes.Blue;
and then myTextBox.ClearValue(MyTextBox.BackgroundProperty);
, it becomes Blue then White again, instead of Red.
I don't understand.
The Background is being set by the default Style of the TextBox. Based on the Dependency Property Value Precedence Red is at #11, while the default Style is at #9. The Blue setting would be at #3, so that should override the Background fine.
You would either have to set the background explicitly (like you do with the Blue brush), or create your own custom default style that doesn't set the Background. Your default style can be based on the TextBox version.
You can set Background
in a style applied to your MyTextBox
:
<Application.Resources>
<Style TargetType="local:MyTextBox">
<Setter Property="Background" Value="Red" />
</Style>
</Application.Resources>
As CodeNaked mentioned your default metadata value is being overriden by default style for textbox. You can see it if you will change your code:
MyTextBox.cs:
Control.BackgroundProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(Brushes.Red,
FrameworkPropertyMetadataOptions.Inherits, PropertyChangedCallback));
private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
// set breakpoint here
}
When breakpoint will be breaked you will be able to see that OldValue
was Red
, NewValue
is White
and from stack-trace you can see that it happens because of default style being applied.
精彩评论