我正在尝试为System.Windows.Controls.Button编写一个ControlTemplate,但是我在附加行为中的动画时遇到了麻烦。具体来说,鼠标悬停在按钮上会产生运行时错误:
InvalidOperationException是 未处理:没有适用的名称范围 存在以解析名称'myBrush'。
当调用sb.Begin()时,会在'ButtonVisualBehavior.cs'文件中发生这种情况(请参阅下面发布的代码)。无论如何,我已经尝试了我能想象到的一切来解决这个问题,而且我仍然遇到麻烦。任何帮助将不胜感激!
以下是代码:
ButtonStyleV.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4">
<Style TargetType="{x:Type Button}" x:Key="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Resources>
<Storyboard x:Key="ButtonStoryboardKey">
<ColorAnimation Storyboard.TargetName="myBrush"
Storyboard.TargetProperty="Color"
From="White"
To="Black"
Duration="0:0:1.0"
RepeatBehavior="Forever"
AutoReverse="True" />
</Storyboard>
</ControlTemplate.Resources>
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Rectangle x:Name="ButtonRect"
Stroke="{x:Null}" Opacity="1"
Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Rectangle.Fill>
<SolidColorBrush x:Name="myBrush" />
</Rectangle.Fill>
</Rectangle>
<ContentPresenter x:Name="ButtonContentPresenter"
Content="{TemplateBinding Button.Content}"
ContentTemplate="{TemplateBinding Button.ContentTemplate}"
HorizontalAlignment="Center" VerticalAlignment="Center">
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="local:ButtonVisualBehaviorV.IsBehaviorAttached" Value="True" />
</Style>
</ResourceDictionary>
ButtonVisualBehavior.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Input;
using System.Windows.Media.Animation;
namespace WpfApplication4
{
class ButtonVisualBehaviorV
{
public static bool GetIsBehaviorAttached(DependencyObject obj)
{
return (bool)obj.GetValue(IsBehaviorAttachedProperty);
}
public static void SetIsBehaviorAttached(DependencyObject obj, bool value)
{
obj.SetValue(IsBehaviorAttachedProperty, value);
}
// Using a DependencyProperty as the backing store for IsBehaviorAttached.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsBehaviorAttachedProperty =
DependencyProperty.RegisterAttached(
"IsBehaviorAttached",
typeof(bool),
typeof(ButtonVisualBehaviorV),
new UIPropertyMetadata(false, OnIsBehaviorAttachedChanged));
private static void OnIsBehaviorAttachedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Button button = d as Button;
if ((button == null) || ((bool)e.NewValue == false))
return;
if (((bool)e.NewValue) == true)
{
button.MouseEnter += Button_MouseEnter;
button.MouseLeave += Button_MouseLeave;
}
else
{
button.MouseEnter -= Button_MouseEnter;
button.MouseLeave -= Button_MouseLeave;
}
}
private static void Button_MouseEnter(object sender, MouseEventArgs e)
{
Button button = sender as Button;
Rectangle buttonRectangle = button.Template.FindName("ButtonRect", button) as Rectangle;
Storyboard sb = buttonRectangle.FindResource("ButtonStoryboardKey") as Storyboard;
sb.Begin();
}
private static void Button_MouseLeave(object sender, MouseEventArgs e)
{
Button button = sender as Button;
Rectangle buttonRectangle = button.Template.FindName("ButtonRect", button) as Rectangle;
Storyboard sb = buttonRectangle.FindResource("ButtonStoryboardKey") as Storyboard;
sb.Begin();
}
}
}
Window2.xaml:
<Window x:Class="WpfApplication4.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
Title="Window2" Height="300" Width="300">
<Grid>
<Button Background="Green" Content="Button" Height="30" HorizontalAlignment="Left" Margin="120,138,0,0" VerticalAlignment="Top" Width="75" />
</Grid>
</Window>
最后,app.xaml:
<Application x:Class="WpfApplication4.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
StartupUri="Window2.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Troubleshooting/ButtonStyleV.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
谢谢!
安德鲁
答案 0 :(得分:0)
您似乎已经解决了眼前的问题,但也许您很欣赏如何以更少的努力完成同样的事情,并且只使用VisualStateManager
这样的XAML:
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="myBrush"
Storyboard.TargetProperty="Color"
From="White"
To="Black"
Duration="0:0:1.0"
RepeatBehavior="Forever"
AutoReverse="True" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed"/>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="ButtonRect"
Stroke="{x:Null}" Opacity="1"
Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Rectangle.Fill>
<SolidColorBrush x:Name="myBrush" />
</Rectangle.Fill>
</Rectangle>
<ContentPresenter x:Name="ButtonContentPresenter"
Content="{TemplateBinding Button.Content}"
ContentTemplate="{TemplateBinding Button.ContentTemplate}"
HorizontalAlignment="Center" VerticalAlignment="Center">
</ContentPresenter>
</Grid>
</ControlTemplate>