2009-03-20 9 views
1

私はXBAPを開発していますが、私は単純な要件があります。WPF - ページ/ウィンドウレベルのViewModelの変更に応答する最善の方法

メインページ全体のDataContextは、UserViewModelのインスタンスに設定されています。 UserViewModelには、Authenticated '、' NotAutheticated '、' AuthenticationFailed 'のような値を持つ列挙型のAuthenticationStateと呼ばれるDependencyPropertyがあります。

ここでは、ページ上のさまざまな要素を非表示にすることで、この値の変化に対応する必要があります。

これを実行する最善の方法は何ですか?

答えて

0

スタイルを使用してソートすることができます。それは痛みですが、それは動作します!

完全な情報源は以下のとおりです。

<Grid x:Name="contentGrid" Grid.Row="1"> 
     <!--login--> 
     <controls:LoginControl> 
      <controls:LoginControl.Style> 
       <Style> 
        <Setter Property="Control.Opacity" Value="0"/> 
        <Setter Property="Control.IsHitTestVisible" Value="False"/> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding Source={StaticResource UserViewModel},Path=UserAuthenticationState}" 
            Value="{x:Static model:AuthenticationState.NotAuthenticated}"> 
          <Setter Property="Control.IsHitTestVisible" Value="True"/> 
          <DataTrigger.EnterActions> 
           <BeginStoryboard> 
            <Storyboard> 
             <DoubleAnimation To="1" Duration="0:0:2" 
                 Storyboard.TargetProperty="Opacity"></DoubleAnimation> 
            </Storyboard> 
           </BeginStoryboard> 
          </DataTrigger.EnterActions> 
          <DataTrigger.ExitActions> 
           <BeginStoryboard> 
            <Storyboard> 
             <DoubleAnimation To="0" Duration="0:0:2" 
                 Storyboard.TargetProperty="Opacity"></DoubleAnimation> 
            </Storyboard> 
           </BeginStoryboard> 
          </DataTrigger.ExitActions> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </controls:LoginControl.Style> 
     </controls:LoginControl>  

     <!--slider--> 
     <slider:PageSlider> 
      <Button>1</Button> 
      <Button>2</Button> 
      <Button>3</Button> 
      <slider:PageSlider.Style> 
       <Style> 
        <Setter Property="Control.Opacity" Value="0"/> 
        <Setter Property="Control.IsHitTestVisible" Value="False"/> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding Source={StaticResource UserViewModel},Path=UserAuthenticationState}" 
            Value="{x:Static model:AuthenticationState.Authenticated}"> 
          <Setter Property="Control.IsHitTestVisible" Value="True"/> 
          <DataTrigger.EnterActions> 
           <BeginStoryboard> 
            <Storyboard> 
             <DoubleAnimation To="1" Duration="0:0:2" 
                 Storyboard.TargetProperty="Opacity"></DoubleAnimation> 
            </Storyboard> 
           </BeginStoryboard> 
          </DataTrigger.EnterActions> 
          <DataTrigger.ExitActions> 
           <BeginStoryboard> 
            <Storyboard> 
             <DoubleAnimation To="0" Duration="0:0:2" 
                 Storyboard.TargetProperty="Opacity"></DoubleAnimation> 
            </Storyboard> 
           </BeginStoryboard> 
          </DataTrigger.ExitActions> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </slider:PageSlider.Style> 
     </slider:PageSlider> 
    </Grid> 
+0

コントロールを折りたたむトリガーが必要です不透明度が0のとき – Steven

0

DataTriggerを使用することをお勧めします。したがって、次のようなものがあります。

<Window.Triggers> 
    <DataTrigger Binding="{Binding AuthenticationState}" Value="NotAuthenticated"> 
     <Setter TargetName="nameOfControl" Property="Visibility" Value="Collapsed" /> 
    </DataTrigger> 
    ... 
    <TextBox x:Name="nameOfControl" /> 
</Window.Triggers> 

UserViewModelオブジェクトがウィンドウのDataContextにある限り、これは機能するはずです。

+0

私はそれを行うことはできません。 Windowは、トリガーコレクション内のEventTriggersのみを受け入れるFrameworkElementです。 – Stimul8d

+0

それは良い点です、私はそれを忘れました。私はほとんどその問題に遭遇することはほとんどありません。なぜなら、私が行うすべてのことがControl/DataTemplatesで行われているからです。 – Steven

3

あなたが言及したように、DataTriggerをコントロールで直接使用することはできません。回避策は、非表示にする必要がある各コントロールのスタイルを使用することです。

<Grid> 
    <Rectangle Fill="Red" /> 
    <Grid.Style> 
     <Style TargetType="Grid"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding Test}" Value="true"> 
        <Setter Property="Visibility" Value="Collapsed" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Grid.Style> 
</Grid> 
+0

また、あなたの他の答えと同じようにあなたのウィンドウのスタイルを設定し、Setter.TargetNameを使用することができます。そうすれば、1つのトリガーと多くのセッターができます。 –

+0

トリガーが使用されているコンテキストのためにTargetNameが解決しないと思うので、それがうまくいくなら私は非常に驚いています。 – Steven

2

好ましい方法は、データコンテキストのAuthenticationStateプロパティにコントロールの可視性プロパティを結合に使用される「AuthenticationStateToVisibilityConverter」と呼ばれるコンバータを使用することであろう。

+0

笑。それが見つかったはずです!金曜日の5時だとは言えません。 – Stimul8d

0

実際には、これを行う最善の方法は、ビューモデルから適切なプロパティを公開することです。これにより、ロジックをより集中化してテストしやすくなります。また、コンバータよりも優れたパフォーマンスを発揮します。結局のところ、ビューモデルです。したがって、ビューをモデル化する必要があります。ビューにパネルの非表示/表示を指示するプロパティが必要な場合は、そのようなプロパティをビューモデルに追加します。

+0

私はそれをやろうとしましたが、そのプロパティへのフックはどこですか?どのトリガー収集を使用してスイッチを実行できますか? – Stimul8d

+0

DependencyObjects(およびDependencyPropertys)をビューモデルに使用することは、慣れていないIMHOです。あなたはINotifyPropertyChangedを実装するPOCOを使用するほうがはるかに優れています。つまり、DependencyPropertyDescriptor.AddValueChanged()を使用して変更を待機することができます。 –

+0

すぐに "ShowViewModel"のようなプロパティの爆発があります。次に、さまざまなシーンに対して期待される動作の違いがあるため、複数の場所で同じViewModelインスタンスを持つことができない場合があります。 Aコンバータはメンテナンスが容易で、テストも簡単です。 – Steven

関連する問題