使用 Silverlight 4 和 WPF 4,我试图创建一个按钮样式,当按钮被鼠标悬停时改变任何包含文本的文本颜色。由于我试图使其与 Silverlight 和 WPF 兼容,因此我正在使用可视状态管理器:
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="outerBorder" CornerRadius="4" BorderThickness="1" BorderBrush="#FF757679">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" To="#FFFEFEFE"
Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)"
Storyboard.TargetName="contentPresenter"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Border x:Name="Background" CornerRadius="3" BorderThickness="1" BorderBrush="Transparent">
<Grid>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}"/>
</Grid>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
由于这是一个普通旧按钮的模板,我知道不能保证里面甚至有一个文本块,起初我不确定这是否可能。奇怪的是,如果按钮声明为:
<Button Content="Hello, World!" />
但如果按钮声明为:
<Button>
<TextBlock Text="Hello, World!" /> <!-- Same result with <TextBlock>Hello, World </TextBlock> -->
</Button>
即使可视化树(在 snoop 中检查时)是相同的(Button -> ContentPresenter -> TextBlock),但需要注意的是,在第一个版本中创建的文本块的数据上下文设置为“Hello, World”,而在第二个版本只是设置了它的 text 属性。我假设这与控件创建的顺序有关(第一个版本的按钮创建 TextBlock,在第二个版本中可能首先创建文本块?真的不确定)。
在研究这个的过程中,我看到了一些在 Silverlight 中工作的解决方案(比如用 ContentControl 替换 ContentPresenter),但在 WPF 中不起作用(程序实际上崩溃了)。
由于这是在按钮的控件模板中,并且如果可能的话我想使用 VSM,我认为这也排除了显式更改按钮自己的 Foreground 属性(我不知道如何从模板中访问它? )
我真的很感激任何帮助,任何人都可以提供的建议。