2012-01-03 46 views
24

私はDataTemplateSelectorとのContentPresenterいる:CurrentStatusが変更された場合、OnPropertyChangedををプロパティが変更されたときにDataTemplateSelectorをトリガする方法

... 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     var model = item as ItemControlViewModel; 

     if (model.CurrentStatus == PrerequisitesStatus.Required) 
     { 
      return RequiredTemplate; 
     } 

     if (model.CurrentStatus == PrerequisitesStatus.Completed) 
     { 
      return FinishedTemplate; 
     } 

     ... 

     return InProgressTemplate; 
    } 

と呼ばれています。

プロパティが変更されたときにこのDataTemplateSelectorをトリガーしてContentPresenter DataTemplateを変更する必要があります。助言がありますか?

Threreも同様の質問です: 1 2、私はので、あまり状態で、任意のDataTriggersを使用する必要はありません。

がDataTriggers

<ContentPresenter 
     Grid.Column="1" 
     Height="16" 
     Width="16" 
     Margin="3"> 
     <ContentPresenter.Triggers> 
      <DataTrigger Binding="{Binding Path=CurrentStatus}" Value="0"> 
       <Setter Property="ContentPresenter.ContentTemplate" Value="{StaticResource ResourceKey=_requiredStatusTemplate}" /> 
      </DataTrigger> 
     </ContentPresenter.Triggers> 
    </ContentPresenter> 

でプレイしようとしましたが、エラーが発生しました: は、コレクションのメンバーは、私が間違っている可能性タイプのEventTrigger :(

+0

あなたはVisualStateManagerを使用して考えがありますか? –

+0

いいえ、私はそれがここには適していないと思います。私はテンプレートではなく、プロパティを変更する必要があります。 – rapt0r

+3

過去に同じ問題が発生していて、DataTriggersに切り替えることで問題は解決しましたが、私はそこにもっと良い解決策があるとは思わないでしょう... – SvenG

答えて

30

、ここにあなたがいる:

A FrameworkElementでのみEventTriggersを持つことができ、したがって、あなたが得るエラーメッセージは、コレクションのメンバーがタイプEventTriggerでなければなりませんトリガ

また、ContentPresenterを直接使用しないでください.ContentTemplateの内部で使用されます。動的コンテンツを作成する場合は、ContentControlを使用する方が効果的です。 What's the difference between ContentControl and ContentPresenter?

最後に、DataTriggerの問題についてご提案します。私は再利用のためのスタイルの内側にそれを入れている....

XAML:テンプレートとは対照的に、apt0r @

<Window x:Class="WpfApplication88.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 

    <DataTemplate x:Key="requiredTemplate"> 
     <TextBlock Text="requiredTemplate"></TextBlock> 
     <!--your stuff here--> 
    </DataTemplate> 

    <DataTemplate x:Key="completedTemplate"> 
     <TextBlock Text="CompletedTemplate"></TextBlock> 
     <!--your stuff here--> 
    </DataTemplate> 

    <Style x:Key="selectableContentStyle" TargetType="{x:Type ContentControl}"> 
     <Style.Triggers> 
     <DataTrigger Binding="{Binding Path=CurrentStatus}" Value="Required"> 
      <Setter Property="ContentTemplate" Value="{StaticResource requiredTemplate}" /> 
     </DataTrigger> 
     <DataTrigger Binding="{Binding Path=CurrentStatus}" Value="Completed"> 
      <Setter Property="ContentTemplate" Value="{StaticResource completedTemplate}" /> 
     </DataTrigger> 
     <!-- your other Status' here --> 
     </Style.Triggers> 
    </Style> 

    </Window.Resources> 

    <Grid> 
    <ContentControl Width="100" Height="100" Style="{StaticResource selectableContentStyle}"/> 
    </Grid> 

</Window> 
+1

素晴らしい!どうもありがとう ;) – rapt0r

6

のものでなければならないのトリガーが、私はDataTemplateSelectorをする場合にのみ使用されていると信じてItemContainerGeneratorは、コレクションに追加された項目のコンテナを作成します。プロパティ値が変更されたときに新しいコンテナが生成されないため、新しいDataTemplateは決してセレクタを介して適用されません。

コメントに示唆されているように、VisualStateManagerまたはデータトリガーを見ることをお勧めします。そうしないと、1つ以上のプロパティーが値を変更したときに、すべてのアイテムのコンテナーを再作成する必要があります。

0

ちょうど余分な選択として - あなたのテンプレートに固執したい場合は、コンバータとのバインディングを使用してください。あなたがコメントでdatatriggersとの例を要求したとして

関連する問題