Лучшее, что я могу придумать, - это добавить прикрепленное поведение, которое отключает это с отражением, как только кнопка будет загружена. Я не знаю, нравится ли вам это лучше, чем перепрограммировать его, но вам не нужно будет включать PresentationFramework.Aero и его повторно используемое
<Button behaviors:DisableButtonChromeBehavior.DisableButtonChrome="True"
...>
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="LightGreen"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="Green"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Foreground" Value="DarkGreen"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
DisableButtonChromeBehavior
public static class DisableButtonChromeBehavior
{
public static readonly DependencyProperty DisableButtonChromeProperty =
DependencyProperty.RegisterAttached
(
"DisableButtonChrome",
typeof(bool),
typeof(DisableButtonChromeBehavior),
new UIPropertyMetadata(false, OnDisableButtonChromePropertyChanged)
);
public static bool GetDisableButtonChrome(DependencyObject obj)
{
return (bool)obj.GetValue(DisableButtonChromeProperty);
}
public static void SetDisableButtonChrome(DependencyObject obj, bool value)
{
obj.SetValue(DisableButtonChromeProperty, value);
}
private static void OnDisableButtonChromePropertyChanged(DependencyObject dpo,
DependencyPropertyChangedEventArgs e)
{
Button button = dpo as Button;
if (button != null)
{
if ((bool)e.NewValue == true)
{
button.Loaded += OnButtonLoaded;
}
else
{
button.Loaded -= OnButtonLoaded;
}
}
}
private static void OnButtonLoaded(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Action action = () =>
{
object buttonChrome = VisualTreeHelper.GetChild(button, 0);
Type type = buttonChrome.GetType();
PropertyInfo propertyInfo = type.GetProperty("RenderMouseOver");
if (propertyInfo != null)
{
propertyInfo.SetValue(buttonChrome, false, null);
propertyInfo = type.GetProperty("RenderPressed");
propertyInfo.SetValue(buttonChrome, false, null);
propertyInfo = type.GetProperty("RenderDefaulted");
propertyInfo.SetValue(buttonChrome, false, null);
}
};
button.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
}
}
Обновление
Существует также более короткий, не подлежащий повторному использованию способ, просто выполняемый в коде.
private void Button_Loaded(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
object buttonChrome = VisualTreeHelper.GetChild(button, 0);
PropertyInfo renderMouseOverInfo = buttonChrome.GetType().GetProperty("RenderMouseOver");
if (renderMouseOverInfo != null)
{
renderMouseOverInfo.SetValue(buttonChrome, false, null);
}
}
Или (если не возражаете, включая Aero)
<Button ...>
<Button.Resources>
<Style TargetType="Microsoft_Windows_Themes:ButtonChrome">
<EventSetter Event="Loaded" Handler="ButtonChrome_Loaded"/>
</Style>
</Button.Resources>
void ButtonChrome_Loaded(object sender, RoutedEventArgs e)
{
ButtonChrome buttonChrome = sender as ButtonChrome;
if (buttonChrome != null)
{
buttonChrome.RenderMouseOver = false;
buttonChrome.RenderPressed = false;
}
}
Кроме этого, я думаю, что у вас нет других выходов, кроме решения, которое вы указали себе (пересматривая).