我创建了一些相当简单的XAML,它完美地运行(至少在KAXML中)。从XAML中调用时,故事板运行完美,但当我尝试从外部访问它时,我得到错误:
'buttonGlow' name cannot be found in the name scope of 'System.Windows.Controls.Button'.
我正在使用流阅读器加载XAML,如下所示:
Button x = (Button)XamlReader.Load(stream);
尝试使用以下命令运行Storyboard:
Storyboard pressedButtonStoryboard =
Storyboard)_xamlButton.Template.Resources["ButtonPressed"];
pressedButtonStoryboard.Begin(_xamlButton);
我认为问题在于我正在制作动画的字段位于模板中,故事板正在访问该按钮。
这是XAML:
<Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:customControls="clr-namespace:pk_rodoment.SkinningEngine;assembly=pk_rodoment"
Width="150" Height="55">
<Button.Resources>
<Style TargetType="Button">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#00FFFFFF">
<Grid.BitmapEffect>
<BitmapEffectGroup>
<OuterGlowBitmapEffect x:Name="buttonGlow" GlowColor="#A0FEDF00" GlowSize="0"/>
</BitmapEffectGroup>
</Grid.BitmapEffect>
<Border x:Name="background" Margin="1,1,1,1" CornerRadius="15">
<Border.Background>
<SolidColorBrush Color="#FF0062B6"/>
</Border.Background>
</Border>
<ContentPresenter HorizontalAlignment="Center"
Margin="{TemplateBinding Control.Padding}"
VerticalAlignment="Center"
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"/>
</Grid>
<ControlTemplate.Resources>
<Storyboard x:Key="ButtonPressed">
<Storyboard.Children>
<DoubleAnimation Duration="0:0:0.4"
FillBehavior="HoldEnd"
Storyboard.TargetName="buttonGlow"
Storyboard.TargetProperty="GlowSize" To="4"/>
<ColorAnimation Duration="0:0:0.6"
FillBehavior="HoldEnd"
Storyboard.TargetName="background"
Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"
To="#FF844800"/>
</Storyboard.Children>
</Storyboard>
<Storyboard x:Key="ButtonReleased">
<Storyboard.Children>
<DoubleAnimation Duration="0:0:0.2"
FillBehavior="HoldEnd"
Storyboard.TargetName="buttonGlow"
Storyboard.TargetProperty="GlowSize" To="0"/>
<ColorAnimation Duration="0:0:0.2"
FillBehavior="Stop"
Storyboard.TargetName="background"
Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"
To="#FF0062B6"/>
</Storyboard.Children>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="ButtonBase.IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource ButtonPressed}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource ButtonReleased}"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Resources>
<DockPanel>
<TextBlock x:Name="TextContent" FontSize="28" Foreground="White" >Test</TextBlock>
</DockPanel>
</Button>
任何了解WPF和XAML的人都比我好多了?
这是错误堆栈跟踪:
at System.Windows.Media.Animation.Storyboard.ResolveTargetName(String targetName, INameScope nameScope, DependencyObject element)
at System.Windows.Media.Animation.Storyboard.ClockTreeWalkRecursive(Clock currentClock, DependencyObject containingObject, INameScope nameScope, DependencyObject parentObject, String parentObjectName, PropertyPath parentPropertyPath, HandoffBehavior handoffBehavior, HybridDictionary clockMappings, Int64 layer)
at System.Windows.Media.Animation.Storyboard.ClockTreeWalkRecursive(Clock currentClock, DependencyObject containingObject, INameScope nameScope, DependencyObject parentObject, String parentObjectName, PropertyPath parentPropertyPath, HandoffBehavior handoffBehavior, HybridDictionary clockMappings, Int64 layer)
at System.Windows.Media.Animation.Storyboard.BeginCommon(DependencyObject containingObject, INameScope nameScope, HandoffBehavior handoffBehavior, Boolean isControllable, Int64 layer)
at System.Windows.Media.Animation.Storyboard.Begin(FrameworkElement containingObject)
at pk_rodoment.SkinningEngine.ButtonControlWPF._button_MouseDown(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at ControlTestbed.App.Main() in C:\svnprojects\rodomont\ControlsTestbed\obj\Debug\App.g.cs:line 0
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
答案 0 :(得分:20)
更改:
pressedButtonStoryboard.Begin(_xamlButton);
要:
pressedButtonStoryboard.Begin(_xamlButton, _xamlButton.Template);
修正了一切。
答案 1 :(得分:5)
我通过重组XAML使其工作,以便SolidColorBrush
和OuterGlowBitmapEffect
是按钮的资源,因此引用的是Storyboard
和它们应用的元素共享至。我就像你一样检索了Storyboard
并在其上调用了Begin()
,但这里是Button
的修改后的XAML:
(请注意密钥"buttonGlow"
和"borderBackground"
以及引用它们的所有StaticResource
标记扩展程序。)
<Button
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="150"
Height="55">
<Button.Resources>
<OuterGlowBitmapEffect
x:Key="buttonGlow"
GlowColor="#A0FEDF00"
GlowSize="0" />
<SolidColorBrush
x:Key="borderBackground"
Color="#FF0062B6" />
<Style
TargetType="Button">
<Setter
Property="Control.Template">
<Setter.Value>
<ControlTemplate
TargetType="Button">
<Grid
Name="outerGrid"
Background="#00FFFFFF"
BitmapEffect="{StaticResource buttonGlow}">
<Border
x:Name="background"
Margin="1,1,1,1"
CornerRadius="15"
Background="{StaticResource borderBackground}">
</Border>
<ContentPresenter
HorizontalAlignment="Center"
Margin="{TemplateBinding Control.Padding}"
VerticalAlignment="Center"
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" />
</Grid>
<ControlTemplate.Resources>
<Storyboard
x:Key="ButtonPressed">
<Storyboard.Children>
<DoubleAnimation
Duration="0:0:0.4"
FillBehavior="HoldEnd"
Storyboard.Target="{StaticResource buttonGlow}"
Storyboard.TargetProperty="GlowSize"
To="4" />
<ColorAnimation
Duration="0:0:0.6"
FillBehavior="HoldEnd"
Storyboard.Target="{StaticResource borderBackground}"
Storyboard.TargetProperty="Color"
To="#FF844800" />
</Storyboard.Children>
</Storyboard>
<Storyboard
x:Key="ButtonReleased">
<Storyboard.Children>
<DoubleAnimation
Duration="0:0:0.2"
FillBehavior="HoldEnd"
Storyboard.Target="{StaticResource buttonGlow}"
Storyboard.TargetProperty="GlowSize"
To="0" />
<ColorAnimation
Duration="0:0:0.2"
FillBehavior="Stop"
Storyboard.Target="{StaticResource borderBackground}"
Storyboard.TargetProperty="Color"
To="#FF0062B6" />
</Storyboard.Children>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger
Property="ButtonBase.IsPressed"
Value="True">
<Trigger.EnterActions>
<BeginStoryboard
Storyboard="{StaticResource ButtonPressed}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard
Storyboard="{StaticResource ButtonReleased}" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Resources>
<DockPanel>
<TextBlock
x:Name="TextContent"
FontSize="28"
Foreground="White">Test</TextBlock>
</DockPanel>
</Button>
答案 2 :(得分:1)
我认为只是遇到了这个问题。
让我推荐您关于此事的博客文章:http://www.cplotts.com/2008/09/26/dr-wpf-namescopes/
基本上,诀窍是你需要使用一个参数来调用Begin,该参数是与故事板所针对的同名范围内的对象。
特别是,从上面的示例中,我将尝试调用Begin并发送对模板中_background元素的引用。
如果这不能解决您的问题,请告诉我。
<强>更新强>
我更喜欢Erickson的解决方案......而且它对我也有用。我不知道我是如何错过Begin方法的重载!
答案 3 :(得分:1)
我也遇到了这个错误。我的情况有点不同,也许更简单。我有一个WPF窗口,其中有一个带有动画的模板。然后我在一个按钮上为一个按钮触发了一个单独的完全不相关的动画,两个都在窗口本身上。我开始得到'在名称范围内找不到'button1'。在玩了一些这里的想法并调试实际的Namescope(看看NameScope.GetNameScope(这个)的结果后,我终于找到解决方案了:
this.RegisterName("button1", this.button1);
在代码中定义并附加到按钮的MouseEnter方法中。将在xaml触发器之前调用此MouseEnter。奇怪的是,如果它在构造函数或Window.Activated()方法中,则register方法不起作用。希望这有助于某人。
答案 4 :(得分:0)
(@ Sam Meldrum)要使STOP工作,请在开头添加'true for“isControllable”
pressedButtonStoryboard.Begin(_xamlButton, _xamlButton.Template);
更改为
pressedButtonStoryboard.Begin(_xamlButton, _xamlButton.Template,true);
现在
pressedButtonStoryboard.Stop(xamlButton)
将起作用