Используя Silverlight 4 и WPF 4, я пытаюсь создать стиль кнопки, который изменяет цвет текста любого содержащегося текста при нажатии кнопки mouseover'd. Поскольку я пытаюсь сделать это совместимым как с 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), с оговоркой, что текстовый блок, созданный в 1-й версии, имеет контекст передачи данных, заданный как "Hello, World", тогда как текстовый блок во второй версии просто имеет свой набор свойств текста. Я предполагаю, что это имеет какое-то отношение к порядку создания управления (первая версия кнопки создает TextBlock, во второй версии текстовый блок может быть создан первым? Действительно не уверен в этом).
В ходе исследования я видел некоторые решения, которые работают в Silverlight (например, заменяя ContentPresenter на ContentControl), но это не будет работать в WPF (программа действительно сбой).
Так как это находится в шаблоне управления кнопками, и я хотел бы использовать VSM, если это возможно, я думаю, что это также исключает явное изменение свойства Button непосредственно переднего плана (я не знаю, как получить доступ к нему изнутри шаблон?)
Я бы очень признателен за любую помощь, советы, которые могли бы дать.