2009-03-29 3 views
0

데이터 바인딩을 통해 관찰 가능 컬렉션에 항목이 추가 된 ItemsControl이 있습니다. 각 항목에는 모양을 정의하는 데이터 템플릿이 있습니다.SIlverlight VSM 상태가 ItemsControl의 대상 항목으로 변경됩니다.

VisualStateManager가 ItemsControl을 특정 상태로 놓았을 때 ItemsControl의 각 항목에 애니메이션을 적용하거나 트리거 할 수 있는지 알아 내려고합니다.

아래 그림은 항목 컨트롤이 닫힌 상태가 될 때입니다. 항목 컨트롤의 항목을 축소하고 텍스트를 숨기고 숫자를 표시하도록합니다. VSM을 사용하여이 작업을 수행 할 수 있습니까? 아니면 애니메이션을 만들 때 각 항목에 애니메이션을 첨부 한 다음 시각적 상태를 변경하려고 할 때 수동으로 애니메이션을 꺼내야합니까? 당신이 실버 라이트 비주얼 상태 매니저에 대해 이야기하는 경우

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

답변

3

ObjectAnimationUsingKeyFrames를 사용하면이 작업을 수행 할 수 있지만 바보 같은 일이 일어나서 머리를 찢어 내고 Visual Studio를 정기적으로 중단 시키며 간단한 방법으로 작업을 수행 할 필요가 거의 없습니다.

간단한 방법 :

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> 

을 다음 연사로 페이지의 :

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); 
      } 
     } 
    } 
} 

는 (: VSM = "CLR-네임 스페이스 : System.Windows; 조립 = System.Windows"XMLNS 포함) :

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

어떻게 페이지에서 사용하는 방법을 :

private void VSMButton_Click(object sender, RoutedEventArgs e) 
    { 
     myVSMControl.Pressed = !myVSMControl.Pressed; 
    } 
: 당신의 페이지에 다음과

  <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" /> 

1

, 나는 이것이 가능하지 두려워.

VisualStates에는 애니메이션이 포함 된 Storyboard 객체 만 포함되어 있습니다. 내가 아는 한 템플릿으로 템플릿을 변경할 수는 없습니다.

WPF VisualStateManager의 기능에 대해 잘 모르겠습니다.

관련 문제