2017-02-02 23 views
1

複数のビューモデルの条件に基づいてスタイルを適用する方法はありますか。2つのビューモデルに基づく条件付き書式設定

例えば、私は条件付きでアイテムレベルでフォーマットすることができる項目のリストを持っているが、私はまた、リスト全体レベルでオンまたはオフに書式設定を有効にすることができるようにしたい:

メインビューモデル

class ParentViewModel : ViewModelBase 
{ 
    public ParentViewModel() 
    { 
     Items = new ObservableCollection<ChildViewModel> { 
      new ChildViewModel{ Display = "I am red", Format=1 }, 
      new ChildViewModel{ Display = "I am red", Format=1 }, 
      new ChildViewModel{ Display = "I am blue", Format=2 }, 
      new ChildViewModel{ Display = "I am blue", Format=2 }, 
     }; 
     ShowFormatting = false; 
    } 

    public ObservableCollection<ChildViewModel> Items { get ... } 

    // I would like to use this property to turn formatting off for the whole list 
    public bool ShowFormatting { get ... } 
} 

がウィンドウに表示される多くのサブビューモデル

class ChildViewModel: ViewModelBase 
{ 
    public string Display { get ... } 

    public int Format { get ... } 
} 

が含まれています

<Window ...> 
    <Grid> 

    <Grid.Resources> 
     <Style x:Key="MyStyle" TargetType="{x:Type TextBlock}"> 
     <Style.Triggers> 
<!-- How can I access ShowFormatting from the main view model here? --> 
      <DataTrigger Binding="{Binding Format}" Value="1"> 
      <Setter Property="Foreground" Value="Red"></Setter> 
      </DataTrigger> 
      <DataTrigger Binding="{Binding Format}" Value="2"> 
      <Setter Property="Foreground" Value="Blue"></Setter> 
      </DataTrigger> 
     </Style.Triggers> 
     </Style> 
    </Grid.Resources> 

    <ListView ItemsSource="{Binding Items}"> 
     <ListView.View> 
     <GridView> 
      <GridViewColumn> 
      <GridViewColumn.CellTemplate> 
<!-- Or can I apply the conditional formatting here? --> 
       <DataTemplate DataType="{x:Type local:ChildViewModel}"> 
       <TextBlock Text="{Binding Display}" Style="{StaticResource MyStyle}"></TextBlock> 
       </DataTemplate> 
      </GridViewColumn.CellTemplate> 
      </GridViewColumn> 
     </GridView> 
     </ListView.View> 
    </ListView> 

    </Grid> 
</Window> 

私が見ている問題は、スタイルがChildViewModelをターゲットにしており、ShowFormattingプロパティにアクセスできないということです。私が思いつくことができる最善の解決策は、ChildViewModelからParentViewModelへのバックリンクを持つことですが、バックリンクを持つことは一般に私にとっては悪いようです。これを行うより良い方法はありますか?

答えて

1

バインドにRelativeSourceを使用することはどうですか?これを行う1つの方法は、2つの異なる子ビューモデル、ChildViewModel1ChildViewModel2を持つことです

<Grid.Resources> 
    <Style x:Key="MyStyle" TargetType="{x:Type TextBlock}"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding Format}" Value="1"> 
     <Setter Property="Foreground" Value="Red"></Setter> 
     </DataTrigger> 
     <DataTrigger Binding="{Binding Format}" Value="2"> 
     <Setter Property="Foreground" Value="Blue"></Setter> 
     </DataTrigger> 
     <DataTrigger Binding="{Binding Path=DataContext.ShowFormatting, RelativeSource={RelativeSource AncestorType=Window}}" Value="SomeValue"> 
     <Setter Property="SomeProperty" Value="SetToThisValue"></Setter> 
     </DataTrigger> 
    </Style.Triggers> 
    </Style> 
</Grid.Resources> 
+0

私はあなたが '... {RelativeSource AncestorType = {x:Type Window}}}}'と思っています。私のデータコンテキストは、ウィンドウより少し上に設定されていましたが、これは機能します。ありがとう。 – Jonny

1

(私はあなたのウィンドウのDataContextのは、タイプParentViewModelであることを、ここで仮定しています)。 ParentViewModelは、Itemsにこれらのタイプの1つまたは両方を設定します。必要に応じてObservableCollection<object>を使用できます。 ChildViewModel1のデータテンプレートとChildViewModel2のデータテンプレートを定義すると、どの子ビューモデルがObservableCollectionにあるかに応じて、それぞれのレンダリングが得られます。

+0

興味深い考えですが、私は上記の例を意図的に簡略化しました(理解しやすくするために単純化することとあまりにも多くを逃さないことのバランスをとることは常に困難です)。実際の例では、左と右のリストがあります。左のアイテムはフォーマットしないでください。アイテムはリスト間を移動できます。 – Jonny

関連する問題