WPF: проблема Namescope с шаблоном управления - PullRequest
0 голосов
/ 08 января 2011

Я пытаюсь написать ControlTemplate для System.Windows.Controls.Button, но у меня постоянно возникают проблемы с анимацией, которая присутствует в прикрепленном поведении.В частности, при наведении курсора на кнопку возникает ошибка времени выполнения:

Исключение InvalidOperationException не обработано: не существует подходящей области имен для разрешения имени «myBrush».

Это происходит вФайл 'ButtonVisualBehavior.cs' при вызове sb.Begin () (см. Код, размещенный ниже).Во всяком случае, я попробовал все, что я могу себе представить, чтобы это исправить, и у меня все еще проблемы.Любая помощь будет принята с благодарностью!

Вот код:

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>

Спасибо!

Андрей

1 Ответ

0 голосов
/ 08 января 2011

Вы, похоже, решили свою непосредственную проблему, но, возможно, вы понимаете, как можно добиться того же результата с гораздо меньшими усилиями и только в XAML, используя VisualStateManager, например:

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...