web-dev-qa-db-ja.com

プロパティが変更されたときにDataTemplateSelectorをトリガーする方法

ContentPresenterに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;
    }

CurrentStatusが変更されると、OnPropertyChangedが呼び出されます。

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

同様の質問があります: 12 ですが、私は望みません状態が多すぎるため、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>

しかし、エラーが発生しました:Triggersコレクションのメンバーは、EventTrigger型である必要があります:(

31
mxpv

コメントにデータトリガーを含む例をリクエストしたので、ここにあります:

FrameworkElementはEventTriggersのみを持つことができるため、エラーメッセージが表示されます。Triggersコレクションメンバーは、EventTriggerタイプである必要があります

また、ContentPresenterを直接使用しないでください。ControlTemplate内で使用するためのものです。動的コンテンツが必要な場合は、ContentControlを使用することをお勧めします。参照 ContentControlとContentPresenterの違いは何ですか?

そして最後に、DataTriggerの問題に対する提案を示します。再利用できるようにスタイルの中に入れています…。

XAML:

<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>
35
SvenG

私は間違っている可能性がありますが、DataTemplateSelectorは、ItemContainerGeneratorがコレクションに追加されたアイテムのコンテナを作成するときにのみ使用されると思います。プロパティ値が変更されても新しいコンテナーは生成されないため、セレクターを介して新しいDataTemplateが適用されることはありません。

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

6
sellmeadog

ちょうど追加の選択肢として-テンプレートを使いたい場合は、コンバーターでsバインディングを使用してください。

2
user572559