2

私は次の問題に対処しようとしています:Expression Blend 3でさまざまな視覚状態のカスタムアニメーションを作成すると、グリッド上の複数の要素のサイズ/不透明度が変更され、グリッド自体ではなく視覚状態グループが作成されますコントロールスタイルで、CustomVisualStateManagerとして定義します。

<Grid x:Name="LayoutRoot" Background="White" Height="500" HorizontalAlignment="Left" VerticalAlignment="Top" Width="500">       
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyVisualStateGroup">
    <VisualStateGroup.Transitions>
    <VisualTransition GeneratedDuration="00:00:00.3000000">
        <VisualTransition.GeneratedEasingFunction>
            <CircleEase EasingMode="EaseIn"/>
    </VisualTransition.GeneratedEasingFunction>
    </VisualTransition>
    </VisualStateGroup.Transitions>
    <VisualState x:Name="State1"/>
    <VisualState x:Name="State2">
        <Storyboard>
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="myBox" Storyboard.TargetProperty="(FrameworkElement.Height)">
            <EasingDoubleKeyFrame KeyTime="00:00:00" Value="360"/>
<!-- omitting other storyboard animations here for clarity -->                      
                </Storyboard>
    </VisualState>
    </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
<VisualStateManager.CustomVisualStateManager>
    <ic:ExtendedVisualStateManager/>
</VisualStateManager.CustomVisualStateManager>

<!-- omitting other grid elements here for clarity -->

</Grid>

私は大丈夫ですが、問題は、コードビハインドで状態を切り替えることができないことです。

VisualStateManager.GoToState(this, "State1", true);

次のように、コントロール自体にはこれらの視覚的状態が定義されていないため、何も起こりません。

VisualStateManager.GetVisualStateGroups(this);

やってみたら

VisualStateManager.GetVisualStateGroups(LayoutRoot);

それは私が必要なものを正確に示しています。しかし、GridではないControlタイプの引数が必要なため、LayoutRootをVisualStateManagerに渡すことはできません。私の質問は、コードビハインドでこのCustomVisualStateManagerの状態にアクセス/変更するにはどうすればよいですか?

4

1 に答える 1

3

CustomVisualStateManagerは、FluidLayoutを有効にしたときにすぐに使用できます。プロジェクトにレイアウトモーフィングが含まれている場合(つまり、状態を使用してあるレイアウトから別のレイアウトにスムーズにアニメーション化しようとしている場合)を除いて、オフに切り替えることができます。カスタムVSMが存在しても、VSMの使用法に違いはありません。

視覚的な状態のマークアップは常に最上位のコンテナ内にあるため、これは完全に正常です。ところで、これはサンプルのタイプミスかもしれませんが、表示するコードは実際には何も含まれていない状態を設定しようとしているため、望ましい結果ではない可能性があります。

それ以外の場合は、UserControlでVisualStateManager.GoToStateを呼び出すと機能するはずです。これが私が今作った例です。

これはシンプルなSilverlightサンプルアプリで、メインページとメインページに追加したユーザーコントロールがあります。メインページは本当にシンプルです:

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SLStateTest"
x:Class="SLStateTest.MainPage"
Width="640" Height="480">

<Grid x:Name="LayoutRoot" Background="White">
    <local:UserControl1 x:Name="TestControl" Height="100" HorizontalAlignment="Left" Margin="24,32,0,0" VerticalAlignment="Top" Width="100"/>
    <Button Height="40" HorizontalAlignment="Left" Margin="192,32,0,0" VerticalAlignment="Top" Width="104" Content="State 1" Click="OnClick"/>
    <Button Height="40" HorizontalAlignment="Left" Margin="192,76,0,0" VerticalAlignment="Top" Width="104" Content="State 2" Click="OnClickState2"/>
</Grid></UserControl>

ユーザーコントロールのインスタンスと2つのボタンがあります。ボタンの機能をすぐに見ていきます。まず、UserControl(UserControl1)を見てみましょう。

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
x:Class="SLStateTest.UserControl1"
d:DesignWidth="280" d:DesignHeight="264">

<Grid x:Name="LayoutRoot" Background="#FF6FFE22">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="Test" ic:ExtendedVisualStateManager.UseFluidLayout="True">
            <VisualState x:Name="State1">
                <Storyboard>
                    <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                        <EasingColorKeyFrame KeyTime="00:00:00" Value="#FF003AFF"/>
                    </ColorAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
            <VisualState x:Name="State2">
                <Storyboard>
                    <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                        <EasingColorKeyFrame KeyTime="00:00:00" Value="#FFFF0202"/>
                    </ColorAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <VisualStateManager.CustomVisualStateManager>
        <ic:ExtendedVisualStateManager/>
    </VisualStateManager.CustomVisualStateManager>
</Grid></UserControl>

ご覧のとおり、1つの視覚状態グループに2つの視覚状態が定義されており、ユーザーコントロールのレイアウトルートに色を設定するだけです。

メインページの2つのボタンは、次のように見えるイベントハンドラーに接続されています。

private void OnClick(object sender, System.Windows.RoutedEventArgs e)
    {
        // TODO: Add event handler implementation here.
        VisualStateManager.GoToState(TestControl, "State1", true);
    }

    private void OnClickState2(object sender, System.Windows.RoutedEventArgs e)
    {
        // TODO: Add event handler implementation here.
        TestControl.SetState();
    }

最初のものは、ページのUserControlでVisualStateManager.GoToStateを呼び出すだけです。2つ目は、同じことを行うユーザーコントロールの関数isideを呼び出します。両方の方法を使用して、両方のオプションが使用可能であることを示しました。UCの外部または内部からVSM.GoToStateを呼び出すことができます。ユーザーコントロールのSetState()メソッドは次のようになります。

public void SetState()
    {
        VisualStateManager.GoToState(this, "State2", true);
    }

アプリを実行すると、ユーザーコントロールは最初に、緑色の基本状態で表示されます。State 1ボタンを押すと、State1に移動し、外部からVSM.GoToState()を呼び出してUCを青色に設定します。状態2ボタンを押すと、内部からVSMを呼び出すことにより、赤に切り替わります。

あなたが投稿したスニペットからは、最初に述べた1つの問題を除いて、何が問題になっているのかわかりません。ただし、私の小さなサンプルは、あなたのケースで何が違うのかを理解するのに役立つかもしれません。

お役に立てば幸いです...

于 2009-11-26T09:59:36.363 に答える