2009-03-29 10 views
0

アイテムを持つItemsControlが、データバインディングを介して観察可能なコレクションに追加されました。各アイテムには、その外観を定義するデータテンプレートがあります。SIlverlight VSM状態がItemsControl内のターゲットアイテムに変更されました

VisualStateManagerがItemsControlを特定の状態に置いたときに、ItemsControl内の各項目にアニメーションを適用/トリガーすることが可能かどうかを調べようとしています。

以下は、アイテムコントロールが閉じた状態になったときの写真です。アイテムコントロール内のアイテムを縮小し、テキストを非表示にして番号が表示されるようにします。これはVSMを使用して可能ですか?アニメーションを作成するときに各アイテムにアタッチし、視覚的な状態を変更したいときは手動でそれらを蹴る必要がありますか?

alt text http://www.edefine.com/images/misc/drawing1.jpg

答えて

3

これはObjectAnimationUsingKeyFramesを使用すると可能ですが、愚かにするのは難しいですが、あなたの髪をリッピングして、ビジュアルスタジオを定期的にクラッシュさせ、簡単なやり方ではほとんど行いません。

簡単な方法:

public class TestSwapContentControl : ContentControl 
{ 
    object StoredOriginalContent; 

    public object FullContent 
    { 
     get { return (object)GetValue(FullContentProperty); } 
     set { SetValue(FullContentProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for FullContent. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty FullContentProperty = 
     DependencyProperty.Register(
      "FullContent" 
      , typeof(object) 
      , typeof(TestSwapContentControl) 
      , null); 

    public void SwitchToFullContent() 
    { 
     if (FullContent != null) 
     { 
      StoredOriginalContent = Content; 
      Content = FullContent; 
     } 
    } 

    public void SwitchToNormalContent() 
    { 
     if(StoredOriginalContent != null) 
     { 
      Content = StoredOriginalContent; 
     } 
    } 
} 

はその後、XAMLを使用する:

<local:TestSwapContentControl x:Name="mySwitch"> 
      <Rectangle Height="50" Width="100" Fill="Black" /> 
     <local:TestSwapContentControl.FullContent> 
       <StackPanel> 
        <TextBlock>1</TextBlock> 
        <TextBlock>2</TextBlock> 
        <TextBlock>3</TextBlock> 
        <TextBlock>4</TextBlock> 
        <Rectangle Height="50" Width="100" Fill="Red" /> 
       </StackPanel> 
      </local:TestSwapContentControl.FullContent> 
    </local:TestSwapContentControl> 

を以下CSがページに:

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     if (myTempBool) 
     { 
      mySwitch.SwitchToFullContent(); 
      myTempBool = false; 
     } 
     else 
     { 
      mySwitch.SwitchToNormalContent(); 
      myTempBool = true; 
     } 
    } 

さて、あなたは本当にする必要がある場合コントロールを他の開発者が完全に拡張可能にするには、visualstatemenagerを使用する必要がありますが、それは本当の雌犬です。ここで

http://scorbs.com/2008/06/11/parts-states-model-with-visualstatemanager-part-1-of/

作業例ですが、私は見えることはできませんとして、それは完璧ではない:あなたは、視覚的状態マネージャを設定する方法を知っているとgeneric.xamlを通じて述べていない場合は、ここではどのように-するガイドですContentPresenterのコンテンツを直接設定します。あなたのgeneric.xamlで

using System.Windows; 
using System.Windows.Controls; 

namespace SilverlightTestApplication 
{ 
    [TemplateVisualState(Name="Normal", GroupName="SizeStates")] 
    [TemplateVisualState(Name="Expanded", GroupName="SizeStates")] 
    public class TestVSMControl : ContentControl 
    { 
     public object SmallContent 
     { 
      get { return (object)GetValue(SmallContentProperty); } 
      set { SetValue(SmallContentProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for SmallContent. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty SmallContentProperty = 
      DependencyProperty.Register("SmallContent", typeof(object), typeof(TestVSMControl), null); 

     public object LargeContent 
     { 
      get { return (object)GetValue(LargeContentProperty); } 
      set { SetValue(LargeContentProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for LargeContent. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty LargeContentProperty = 
      DependencyProperty.Register("LargeContent", typeof(object), typeof(TestVSMControl), null); 

     public bool Pressed 
     { 
      get { return (bool)GetValue(PressedProperty); } 
      set { SetValue(PressedProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for Pressed. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty PressedProperty = 
      DependencyProperty.Register("Pressed", typeof(bool), typeof(TestVSMControl), 
       new PropertyMetadata(new PropertyChangedCallback(PressedPropertyChanged))); 

     static void PressedPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
     { 
      var me = sender as TestVSMControl; 
      me.ChangeState(); 
     } 

     public TestVSMControl() 
     { 
      DefaultStyleKey = typeof(TestVSMControl); 
     } 

     void ChangeState() 
     { 
      GoToState(true); 
     } 

     private void GoToState(bool useTransitions) 
     { 
      if (Pressed) 
      { 
       VisualStateManager.GoToState(this, "Normal", useTransitions); 
      } 
      else 
      { 
       VisualStateManager.GoToState(this, "Expanded", useTransitions); 
      } 
     } 
    } 
} 

(のxmlns含ま:VSM = "CLR名前空間:System.Windows;アセンブリ= System.Windows"):

<Style TargetType="local:TestVSMControl">   
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="local:TestVSMControl"> 
       <StackPanel> 
        <vsm:VisualStateManager.VisualStateGroups> 
         <vsm:VisualStateGroup x:Name="SizeStates"> 
          <vsm:VisualState x:Name="Normal"> 
           <Storyboard> 
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Storyboard.TargetName="myContentPresenter" BeginTime="00:00:00" Duration="00:00:00.0010000" > 
             <ObjectAnimationUsingKeyFrames.KeyFrames> 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
                <StackPanel> 
                 <TextBlock>Rararasputin</TextBlock> 
                 <Button Content="{TemplateBinding SmallContent}" /> 
                </StackPanel> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames.KeyFrames> 
            </ObjectAnimationUsingKeyFrames> 
           </Storyboard> 
          </vsm:VisualState> 
          <vsm:VisualState x:Name="Expanded"> 
           <Storyboard> 
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Storyboard.TargetName="myContentPresenter" BeginTime="00:00:00" Duration="00:00:00.0010000" > 
             <ObjectAnimationUsingKeyFrames.KeyFrames> 
              <DiscreteObjectKeyFrame KeyTime="0:0:0" > 
               <DiscreteObjectKeyFrame.Value> 
                <StackPanel> 
                 <TextBlock>Other one</TextBlock> 
                 <Button Content="{TemplateBinding LargeContent}" /> 
                </StackPanel> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames.KeyFrames> 
            </ObjectAnimationUsingKeyFrames> 
           </Storyboard> 
          </vsm:VisualState> 
         </vsm:VisualStateGroup> 
        </vsm:VisualStateManager.VisualStateGroups>       
        <ContentPresenter x:Name="myContentPresenter" /> 
       </StackPanel> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

そして、どのように自分のページで使用すると:あなたのページで、次のと

  <local:TestVSMControl x:Name="myVSMControl" Height="200"> 
       <local:TestVSMControl.SmallContent> 
        <Rectangle Height="50" Width="100" Fill="Red" /> 
       </local:TestVSMControl.SmallContent> 
       <local:TestVSMControl.LargeContent> 
        <Rectangle Height="50" Width="100" Fill="Green" /> 
       </local:TestVSMControl.LargeContent>   
      </local:TestVSMControl> 
      <Button Content="Swap" x:Name="VSMButton" Click="VSMButton_Click" /> 

private void VSMButton_Click(object sender, RoutedEventArgs e) 
    { 
     myVSMControl.Pressed = !myVSMControl.Pressed; 
    } 
1

あなたはSilverlightのビジュアルステートマネージャーの話をしている場合は、私はこれが不可能である怖いです。

VisualStatesにはStoryboardオブジェクトのみが含まれ、アニメーションも含まれます。私が知る限り、あなたはテンプレートを変更することはできません。

WPF VisualStateManagerの機能についてはわかりません。

関連する問題