Domanda

Ho creato un XAML abbastanza semplice e funziona perfettamente (almeno in KAXML). Gli storyboard funzionano perfettamente quando vengono chiamati dall'interno di XAML, ma quando provo ad accedervi dall'esterno ottengo l'errore:

'buttonGlow' name cannot be found in the name scope of 'System.Windows.Controls.Button'.

Sto caricando XAML con un lettore di stream, in questo modo:

Button x = (Button)XamlReader.Load(stream);

E cercando di eseguire lo Storyboard con:

Storyboard pressedButtonStoryboard =   
    Storyboard)_xamlButton.Template.Resources["ButtonPressed"];
pressedButtonStoryboard.Begin(_xamlButton);

Penso che il problema sia che i campi che sto animando sono nel modello e che lo storyboard sta accedendo al pulsante.

Ecco 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>

Qualche suggerimento di chiunque capisca WPF e XAML molto meglio di me?

Ecco l'errore 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()
È stato utile?

Soluzione

Finalmente l'ho trovato. Quando chiami Inizia su storyboard che fanno riferimento a elementi in ControlTemplate, devi passare anche nel modello di controllo.

Modifica:

pressedButtonStoryboard.Begin(_xamlButton);

A:

pressedButtonStoryboard.Begin(_xamlButton, _xamlButton.Template);

Risolto tutto.

Altri suggerimenti

L'ho fatto funzionare ristrutturando XAML in modo che SolidColorBrush e OuterGlowBitmapEffect fossero risorse del pulsante e quindi referenziate fossero condivise dal Storyboard se gli elementi a cui sono applicati. Ho recuperato il Storyboard e ho chiamato Begin () proprio come hai fatto tu, ma ecco la XAML modificata per il pulsante :

(Nota le chiavi " buttonGlow " e " borderBackground " e tutte le estensioni di markup StaticResource che fanno riferimento a loro.)

<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>

Penso che abbia avuto questo problema.

Consentitemi di rimandarvi al mio post di blog sull'argomento: http://www.cplotts.com/2008/09/26/dr-wpf-namescopes/

Fondamentalmente, il trucco è che devi chiamare Inizia con un argomento che è un oggetto con lo stesso nome che gli storyboard stanno prendendo di mira.

In particolare, dal tuo esempio sopra, proverei a chiamare Begin e invio un riferimento all'elemento _background nel tuo modello.

Fammi sapere se questo non risolve il tuo problema.

Aggiornamento:

Mi piace la soluzione di Erickson meglio della mia ... e ha funzionato anche per me. Non so come ho perso quel sovraccarico del metodo Begin!

Ho riscontrato anche questo errore. La mia situazione è un po 'diversa, forse più semplice. Ho una finestra WPF che ha un modello con un'animazione. Ho quindi avuto un'animazione completamente indipendente, attivata da MouseEnter, definita per un pulsante, entrambi sulla finestra stessa. Ho iniziato a ottenere 'button1 non può essere trovato nel telescopio'. Dopo aver giocato un po 'con alcune delle idee qui e aver eseguito il debug dell'attuale Namescope (dai un'occhiata al risultato di NameScope.GetNameScope (questo), ho finalmente trovato la soluzione da mettere:

 this.RegisterName("button1", this.button1);

in un metodo MouseEnter definito nel codice e collegato al pulsante. Questo MouseEnter verrà chiamato prima del trigger xaml. Curiosamente, il metodo register non funziona se è nel costruttore o nel metodo Window.Activated (). Spero che questo aiuti qualcuno.

(@ Sam Meldrum) Per far funzionare STOP, aggiungi 'true per " isControllable " all'inizio

pressedButtonStoryboard.Begin(_xamlButton, _xamlButton.Template);

cambia in

pressedButtonStoryboard.Begin(_xamlButton, _xamlButton.Template,true);

e ora

pressedButtonStoryboard.Stop(xamlButton)

funzionerà

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top