2011-03-25 110 views
4

我做了一个非常简单的测试项目:忽略元数据覆盖?

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; 
     } 
    } 
} 

这是为了测试metaData Overriding函数。

现在麻烦的是:因为我预料到这个不工作...

事实上,MyTextBox的背景是白色的,而不是红色。

我调查,并试图以此作为构造为我的自定义类:

public MyTextBox(string Content) 
{ 
    Text = Content; 
    Background = Brushes.Blue; 
    ClearValue(BackgroundProperty); 
} 

现在这里是我发现了什么,当我调试:

在主类:

MyTextBox myTextBox = new MyTextBox("some text here"); 

我们进入自定义类的静态构造函数,然后在实例的构造函数中:

Text = Content; >>背景=红

Background = Brushes.Blue; >>背景=蓝色

ClearValue(BackgroundProperty); >>背景=红了起来(如预期)

我们回到主类:

mainPanel.Children.Add(myTextBox); 

...并且在这行代码之后,myTextBox.Background是白色。

问:为什么?

为什么当我将它添加到mainPanel时,它被设置为白色?此外,如果我再添加一些代码,例如:myTextBox.Background = Brushes.Blue;,然后myTextBox.ClearValue(MyTextBox.BackgroundProperty);,它会变成蓝色,然后是白色,而不是红色。

我不明白。

回答

2

背景正在由TextBox的默认样式设置。基于Dependency Property Value Precedence Red在#11,而默认Style在#9。蓝色设置将在#3,所以应该覆盖背景精细。

您将不得不明确地设置背景(就像您使用蓝色笔刷一样),或者创建您自己的未设置背景的自定义默认样式。您的默认样式可以基于TextBox版本。

+0

我很怀疑,但一直没能找到这种风格优先文件。虽然这有点奇怪...它损害了元数据的可用性。在我看来是覆盖。 (在视觉特性方面无效) – David 2011-03-25 13:05:50

2

您可以应用到您的MyTextBox样式集Background

<Application.Resources> 
    <Style TargetType="local:MyTextBox"> 
     <Setter Property="Background" Value="Red" /> 
    </Style> 
</Application.Resources> 

由于CodeNaked提到您的默认元数据值正在被用于文本框的默认样式覆盖。你可以看到它,如果你会改变你的代码:

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 
    } 

当断点被breaked,你将能够看到OldValueRedNewValueWhite和堆栈跟踪你可以看到它发生是因为应用了默认样式。