我做了一个非常简单的测试项目:
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覆盖函数。
现在麻烦的是:这不像我预期的那样......
实际上,MyTextBox的背景是白色的,而不是红色。我调查并尝试将其作为自定义类的构造函数:
public MyTextBox(string Content)
{
Text = Content;
Background = Brushes.Blue;
ClearValue(BackgroundProperty);
}
现在这是我在调试时发现的:
主要课程中的:
MyTextBox myTextBox = new MyTextBox("some text here");
我们进入自定义类的静态构造函数,然后进入实例的构造函数:
Text = Content;
&gt;&gt;背景=红色
Background = Brushes.Blue;
&gt;&gt;背景=蓝色
ClearValue(BackgroundProperty);
&gt;&gt;背景=再次红色(如预期的那样)
我们回到主要课程:
mainPanel.Children.Add(myTextBox);
...就在这行代码之后,myTextBox.Background
是白色。
问题:为什么?
为什么在将它添加到mainPanel时将其设置为白色?我找不到任何合乎逻辑的解释......
此外,如果我添加更多代码,我会执行以下操作:myTextBox.Background = Brushes.Blue;
然后myTextBox.ClearValue(MyTextBox.BackgroundProperty);
,它会再次变为蓝色然后是白色,而不是红色。
我不明白。
答案 0 :(得分:2)
背景由TextBox的默认样式设置。基于Dependency Property Value Precedence Red位于#11,而默认Style位于#9。蓝色设置为#3,因此应该覆盖背景精细。
您可能必须明确设置背景(就像使用蓝色画笔一样),或者创建自己的不设置背景的自定义默认样式。您的默认样式可以基于TextBox版本。
答案 1 :(得分:2)
您可以在应用于Background
的样式中设置MyTextBox
:
<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
}
当断点断开时,您将能够看到OldValue
为Red
,NewValue
为White
,并且从堆栈跟踪中您可以看到它发生,因为正在应用的默认样式。