2012-01-12 7 views
0

私はWPF(.NET 4)でアプリケーションを開発しています。添付プロパティのコールバックで受け取ったDependyObjectのテンプレートを取得します。

コントロールが「有効」状態にあるかどうかを簡単に判断するために作成した添付プロパティがあります。

/// <summary> 
    /// Initializes static members of the <see cref="ValidationProperty"/> class. 
    /// </summary> 
    static ValidationProperty() 
    { 
     // Register attached dependency property. 
     IsValidProperty = DependencyProperty.RegisterAttached("IsValid", typeof(bool), 
                   typeof(ValidationProperty), 
                   new FrameworkPropertyMetadata(true, ValidationValueChanged)); 
    } 

    (...) 

    /// <summary> 
    /// Gets or sets the Dependency Property used to determine if an element is valid. 
    /// </summary> 
    public static DependencyProperty IsValidProperty { get; set; } 

    (...) 

値がfalseのときはいつでもアニメーションを再生したいと思います。アニメーションは、コントロール自体またはテンプレート内で定義することができます。ストーリーボードの名前は常に一定です。つまり、「InvalidInput」です。

/// <summary> 
    /// Event raised when the "Is Valid" dependency property's value changes. 
    /// </summary> 
    /// <param name="sender">The object that raised the event.</param> 
    /// <param name="e">The arguments passed to the event.</param> 
    private static void ValidationValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     var invalidControl = sender as UserControl; 

     if (invalidControl == null || !(e.NewValue is bool)) 
     { 
      return; 
     } 

     var isValid = (bool)e.NewValue; 

     if (isValid) 
     { 
      return; 
     } 

     var userControlInvalidInputStoryboard = invalidControl.Resources["InvalidInput"] as Storyboard; 
     var templatedInvalidInputStoryboard = invalidControl.Template.Resources["InvalidInput"] as Storyboard; 

     if (userControlInvalidInputStoryboard != null) 
     { 
      userControlInvalidInputStoryboard.Begin(invalidControl); 
      return; 
     } 

     if (templatedInvalidInputStoryboard != null) 
     { 
      templatedInvalidInputStoryboard.Begin(invalidControl, invalidControl.Template); 
      return; 
     } 
    } 

今の問題は、私がコントロールまたはそのテンプレートのいずれかの中に定義されたストーリーボードを見つけることができませんよということです。

は、ここに私のコールバックです。 userControlInvalidInputStoryboardおよびtemplatedInvalidInputStoryboardはnullです。

これは、依存オブジェクトが実際の型ではなくユーザーコントロールにキャストされているためです。

テンプレートとそのストーリーボードを取得する方法はありますか?

編集:要求されたとして、ここではこの添付プロパティ

<UserControl 
    (...) 
xmlns:AttachedProperties="clr-namespace:Controls.AttachedProperties" 
x:Name="Root"> 
<Grid x:Name="LayoutRoot"> 
    <TextBox x:Name="TextBox" 
      Text="{Binding Path=(AttachedProperties:TextProperty.Text), UpdateSourceTrigger=PropertyChanged, 
          RelativeSource={RelativeSource AncestorType={x:Type Custom:UsernameTextBox}}, Mode=TwoWay, 
          TargetNullValue={x:Static Custom:UsernameTextBox.DefaultKeyword}, FallbackValue=DefaultKeyword}" 
      HorizontalAlignment="Left" Width="292" Style="{DynamicResource StandardTextBoxStyle}" 
      Height="35" VerticalAlignment="Top" TabIndex="0" 
      MaxLines="1" MaxLength="30" 
      FontSize="16" GotFocus="TextBoxGotFocus" LostFocus="TextBoxLostFocus" TextChanged="TextBoxTextChanged" FontWeight="Bold"/> 
</Grid> 

を使用して、コントロールのXAMLであり、ここで私は制御インスタンス化方法は次のとおりです。

<Custom:UsernameTextBox x:Name="UsernameTextbox" 
    AttachedProperties:ValidationProperty.IsValid="{Binding CodexLoginService.UsernameIsValid, UpdateSourceTrigger=PropertyChanged}" 
    AttachedProperties:TextProperty.Text="{Binding CodexLoginService.Username, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
    KeyUp="OnUsernameChanged"/> 

編集#2 :提案したように、私はテンプレート内にVisual State Groupを作成しました:

 <VisualStateGroup x:Name="InvalidStates"> 
      <VisualStateGroup.Transitions> 
       <VisualTransition GeneratedDuration="0:0:0.2" To="Invalid"/> 
      </VisualStateGroup.Transitions> 
      <VisualState x:Name="Invalid"> 
       <Storyboard> 
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="InvalidFrame"> 
         <EasingDoubleKeyFrame KeyTime="0" Value="1"/>       </DoubleAnimationUsingKeyFrames> 
       </Storyboard> 
      </VisualState> 
     </VisualStateGroup> 

コントロールの状態が動作しない変更しようとすると、メソッドはfalseを返します。

VisualStateManager.GoToState(invalidControl, "Invalid", true); 
+0

コントロールのXAMLを提供できますか? – Clemens

+0

@クレメンス:確かに、私は:)。 –

+0

しかし、リソース辞書は表示されません – Clemens

答えて

2

あなたがVisualStatesを実装する場合は、アニメーションの名前を忘れて、ちょうど状態を変更することができます。チェックthis article

+0

私はそれについてもっと読んで、それが私を助けることができるかどうかを見ていきます。 –

+0

完全に合意して、視覚状態ははるかに良いアプローチになります。 – Clemens

+0

私は視覚的な状態を作成し、GoToState(...)メソッドはfalseを返し続けます。私が使用しているコードは次のとおりです:VisualStateManager.GoToState(invalidControl、 "Invalid"、true); 何か不足していますか?必要に応じて、最初の投稿を視覚的な状態のグループ定義で更新します。 –

関連する問題