情节提要板找不到ControlTemplate元素
时间:2020-03-06 14:54:24 来源:igfitidea点击:
我已经创建了一些相当简单的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 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的了解比我强得多的人有什么建议吗?
这是错误stacktrace:
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()
解决方案
我想只是有这个问题。
让我向我们介绍有关此事的博客条目:http://www.cplotts.com/2008/09/26/dr-wpf-namescopes/
基本上,诀窍是我们需要调用一个以参数为起点的参数,该参数是一个与情节提要所针对的名称范围相同的对象。
特别是,从上面的示例中,我将尝试调用Begin并发送对模板中_background元素的引用。
让我知道这是否不能解决问题。
终于找到了。在引用了ControlTemplate中元素的情节提要板上调用Begin时,还必须传递控件模板。
变更:
pressedButtonStoryboard.Begin(_xamlButton);
到:
pressedButtonStoryboard.Begin(_xamlButton, _xamlButton.Template);
修复了所有问题。
我通过重组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>