0

監視可能なコレクションへのデータバインディングを通じて項目が追加されたItemsControlがあります。各アイテムには、その外観を定義するデータ テンプレートがあります。

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

以下は写真です-アイテムコントロールが閉じた状態になったとき-アイテムコントロールのアイテムを縮小してテキストを非表示にし、数字を表示させたいです。これは VSM を使用して可能ですか、それとも作成時に各アイテムにアニメーションを添付し、視覚的な状態を変更したいときに手動で開始する必要がありますか?

代替テキスト http://www.edefine.com/images/misc/drawing1.jpg

4

2 に答える 2

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 を使用する必要がありますが、これは非常に面倒です。generic.xaml を使用してビジュアル ステート マネージャーとステートを設定する方法がわからない場合は、次のハウツー ガイドを参照してください。

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

これは実際の例ですが、 ContentPresenter のコンテンツを直接設定できないように見えるため、完全ではありません。

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

generic.xaml に (xmlns:vsm="clr-namespace:System.Windows;assembly=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;
    }
于 2009-04-02T09:36:23.153 に答える
1

Silverlight Visual State Manager について話しているのであれば、残念ながらこれは不可能です。

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

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

于 2009-03-29T02:05:37.590 に答える