2011-01-08 10 views
0

System.Windows.Controls.Button用のControlTemplateを書き込もうとしていますが、添付された動作のアニメーションに問題があります。具体的には、ボタンの上にマウスを置いすると、実行時エラーを生成しますsb.Beginは()(コードは以下の投稿を参照)が呼び出されたときにWPF:コントロールテンプレートの名前スコープの問題

InvalidOperationException was unhandled: No applicable name scope exists to resolve the name 'myBrush'.

これは「ButtonVisualBehavior.cs」ファイルに起こります。とにかく、私はこれを修正するために想像できるすべてを試してきましたが、まだ問題があります。どんな助けでも大歓迎です!

ここでは、コードです:

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> 

ありがとう!

あなたの当面の問題を解決しますが、おそらくあなたは、あなただけのようVisualStateManagerを使用してはるかに少ない労力でとXAMLで同じことを達成することができますどのように感謝しているように見えたアンドリュー

+0

うーん...私は、StoryboardリソースをControlTemplate.Resourcesから子のGrid.Resourcesコレクション(これはButtonStyleV.xamlファイルにあります)に移動すると、すべてうまく動作することに気付きました。私はちょうど理由がわかりません... – Andrew

答えて

0

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

ありがとうリック、あなたは解決策はかなり良いです。私はおそらく、添付の動作に固執しようとしています。なぜなら、これを引っ張ったコードは、C#でもっと簡単なボタンの視覚的な変更を必要とするからです。あなたは解決策がよりエレガントなように見えます。 – Andrew