4

MainWindow の LayoutRoot Grid で次のように定義された 2 つのビジュアル ステートがあります。

<Grid x:Name="LayoutRoot" Background="#FF434343" ShowGridLines="True">

<Grid.RowDefinitions>
    <RowDefinition Height="100"/>
    <RowDefinition Height="*"/>
</Grid.RowDefinitions>


    <VisualStateManager.CustomVisualStateManager>
        <ic:ExtendedVisualStateManager/>
    </VisualStateManager.CustomVisualStateManager>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="VisualStateLogin">
            <VisualStateGroup.Transitions>
                <VisualTransition GeneratedDuration="00:00:00.6000000"/>
            </VisualStateGroup.Transitions>
            <VisualState x:Name="LoggedOn">
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="{x:Null}" Storyboard.TargetProperty="(Window.WindowStyle)">
                        <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static WindowStyle.None}"/>
                    </ObjectAnimationUsingKeyFrames>
                    <BooleanAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="{x:Null}" Storyboard.TargetProperty="(Window.AllowsTransparency)">
                        <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="True"/>
                    </BooleanAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
            <VisualState x:Name="LoggedOff">
                <Storyboard>
                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="brdContent" Storyboard.TargetProperty="(UIElement.Opacity)">
                        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.1"/>
                    </DoubleAnimationUsingKeyFrames>
                    <BooleanAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="brdContent" Storyboard.TargetProperty="(UIElement.IsEnabled)">
                        <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False"/>
                    </BooleanAnimationUsingKeyFrames>
                    <BooleanAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="ucTabButtons" Storyboard.TargetProperty="(UIElement.IsEnabled)">
                        <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False"/>
                    </BooleanAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="ucTabButtons" Storyboard.TargetProperty="(UIElement.Opacity)">
                        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.4"/>
                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

次のように、MainWindow のコード ビハインドを考慮して、ある状態から別の状態に切り替えると問題なく動作します。

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        //ExtendedVisualStateManager.GoToElementState(this.LayoutRoot as FrameworkElement, "LoggedOff", false);        
    }

しかし今、MainWindow内のユーザーコントロールから状態を切り替えることができる必要があります...

私はそれを試しました:

    private void btnOk_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        MainWindow parent = new MainWindow();
        Grid root = new Grid();
        root = (Grid)parent.FindName("LayoutRoot");
        ExtendedVisualStateManager.GoToElementState(root as FrameworkElement, "LoggedOn", true);
    }

そして、それは私に次の例外を与えます:

System.NullReferenceException は処理されませんでした Message="オブジェクト参照がオブジェクトのインスタンスに設定されていません。" ソース="WPFToolkit"

誰かがユーザーコントロールから状態を切り替える方法を知っていますか?

ありがとうございました、

ジョシ

4

2 に答える 2

1

状態を切り替えるためのインターフェイスを定義することをお勧めします。フォームはインターフェイスを実装でき、インターフェイスをコントロールに明示的に渡すか、コントロールが親にクエリを実行してインターフェイスが実装されているかどうかを確認できます。このように、ユーザーコントロールはコンテナーに緊密に結合されておらず、コンテナーが提供することを期待する動作にのみ結合されます。

ちなみに、ユーザーコントロールでコンテナーの状態を変更するのは、珍しい設計です。要件を構成する別の方法があるかどうかを検討することをお勧めします。

可能なインターフェース:

public interface IStateChanger
{
    void GoToElementState(string state);    
}

MainWindowにこのインターフェースを実装させることができます:

    void IStateChanger.GoToElementState(string state)
    {
        ExtendedVisualStateManager.GoToElementState(this.LayoutRoot as FrameworkElement, state, false);        
    }

次に、あなたの例に従って、あなたのコントロールはこれを行うことができます:

    private void btnOk_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        MainWindow parent = new MainWindow();
        if (parent is IStateChanger)
            ((IStateChanger)parent).GoToElementState("LoggedOn");
    }
于 2010-03-07T13:37:53.670 に答える
0

親がサブスクライブできるユーザー コントロールでパブリック イベントを作成します。このイベントは、状態遷移のトリガーとして使用できます。

于 2010-03-08T02:26:49.407 に答える