2012-01-03 23 views
24

que tienen ContentPresenter con DataTemplateSelector:Cómo activar DataTemplateSelector cuando la propiedad cambia?

... 

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

Cuando se cambia CurrentStatus, OnPropertyChanged se llama.

Necesito de alguna manera activar este DataTemplateSelector cuando se cambie la propiedad y cambie ContentPresenter DataTemplate. ¿Alguna sugerencia?

threre son preguntas similares: 1 2, pero no quiero utilizar cualquier DataTriggers, debido al exceso de estados.

tratado de jugar con 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> 

Pero tiene un error: desencadenantes miembros de la colección debe ser de tipo EventTrigger :(

+0

@ apt0r Ha considerado el uso VisualStateManager a diferencia de plantillas? –

+0

No, creo que no es adecuado aquí. Necesito cambiar la plantilla, no una propiedad. – rapt0r

+3

Tuve el mismo problema en el pasado y cambié a DataTriggers para que funcione, no creo que haya una mejor solución para esto ... – SvenG

Respuesta

30

Como usted solicitó un ejemplo con datatriggers en los comentarios, aquí están:

FrameworkElement sólo puede tener Eventtriggers, por lo tanto, se obtiene el mensaje de error Activadores miembros de la colección deben ser del tipo EventTrigger

Y tampoco use un ContentPresenter directamente, está destinado a ser utilizado dentro de ControlTemplate. Mejor utilizar un ContentControl cuando desee tener contenido dinámico. Ver What's the difference between ContentControl and ContentPresenter?

Y, finalmente, aquí hay una sugerencia para su problema DataTrigger. He ponerlo dentro de un estilo para la reutilización ....

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> 
+1

¡Genial! Muchas gracias ;) – rapt0r

6

Podría estar equivocado, pero creo que el DataTemplateSelector sólo se utiliza cuando el ItemContainerGenerator crea un contenedor para un artículo agregado a la colección. Como no se genera un nuevo contenedor cuando cambia el valor de una propiedad, nunca se aplicará un nuevo DataTemplate a través del selector.

Como se sugirió en los comentarios, le recomendaría que consulte VisualStateManager o desencadenadores de datos; de lo contrario, tendrá que volver a crear el contenedor para cada elemento cuando una o más propiedades cambien de valor.

0

Simplemente como una opción extra: si desea atenerse a sus plantillas, simplemente use s binding con convertidor.

Cuestiones relacionadas