لا يمكن للقصص المصورة العثور على عناصر ControlTemplate

StackOverflow https://stackoverflow.com/questions/151752

سؤال

لقد قمت بإنشاء بعض 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()
هل كانت مفيدة؟

المحلول

وأخيرا وجدت ذلك.عند استدعاء "البدء" في القصص المصورة التي تشير إلى العناصر الموجودة في ControlTemplate، يجب عليك تمرير قالب التحكم أيضًا.

التغيير:

pressedButtonStoryboard.Begin(_xamlButton);

ل:

pressedButtonStoryboard.Begin(_xamlButton, _xamlButton.Template);

ثابت كل شيء.

نصائح أخرى

لقد نجحت في ذلك من خلال إعادة هيكلة XAML بحيث يمكن لـ SolidColorBrush و OuterGlowBitmapEffect كانت موارد الزر وبالتالي تتم مشاركتها بواسطة Storyboards والعناصر التي يتم تطبيقها عليها.لقد استرجعت Storyboard ودعا Begin() عليه تمامًا كما فعلت، ولكن هنا هو XAML المعدل لـ Button:

(يرجى ملاحظة المفاتيح "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>

أعتقد أن هذه المشكلة كانت للتو.

دعني أحيلك إلى مدخل مدونتي حول هذا الموضوع: http://www.cplotts.com/2008/09/26/dr-wpf-namescopes/

في الأساس، الحيلة هي أنك تحتاج إلى استدعاء "البدء" بوسيطة تمثل كائنًا في نفس نطاق الاسم الذي تستهدفه القصص المصورة.

على وجه الخصوص، من العينة أعلاه، سأحاول الاتصال بـ Begin وإرسال إشارة إلى عنصر _background في القالب الخاص بك.

اسمحوا لي أن أعرف إذا كان هذا لا يحل مشكلتك.

تحديث:

أنا أحب حل إريكسون أفضل من حلي ...وعملت بالنسبة لي أيضا.لا أعرف كيف فاتني هذا الحمل الزائد لطريقة البدء!

لقد وقعت في هذا الخطأ أيضًا.وضعي مختلف بعض الشيء، وربما أبسط.لدي نافذة WPF بها قالب به رسم متحرك.بعد ذلك، حصلت على رسم متحرك منفصل وغير مرتبط تمامًا تم تشغيله بواسطة MouseEnter محددًا لزر، وكلاهما على النافذة نفسها.لقد بدأت في الحصول على "لا يمكن العثور على الزر 1 في نطاق الاسم".بعد تجربة بعض الأفكار هنا وتصحيح أخطاء Namescope الفعلي (راقب نتيجة NameScope.GetNameScope(this)، وجدت أخيرًا أن الحل هو وضع:

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

في طريقة MouseEnter المحددة في الكود والمرفقة بالزر.سيتم استدعاء MouseEnter هذا قبل مشغل xaml.من الغريب أن طريقة التسجيل لا تعمل إذا كانت في طريقة المُنشئ أو طريقة Window.Activated().أمل أن هذا يساعد شخصاما.

(@ Sam Meldrum) لكي يعمل STOP، أضف "صحيح" لـ "isControllable" في البداية

pressedButtonStoryboard.Begin(_xamlButton, _xamlButton.Template);

تغيير ل

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

و الأن

pressedButtonStoryboard.Stop(xamlButton)

سيعمل

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top