c# - ¿Cómo activar DataTemplateSelector cuando la propiedad cambia?
wpf (3)
Tengo ContentPresenter con 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;
}
Cuando se cambia CurrentStatus, se llama a OnPropertyChanged.
Necesito de alguna manera activar este DataTemplateSelector cuando se cambie la propiedad y cambiar ContentPresenter DataTemplate. ¿Alguna sugerencia?
Hay preguntas similares: 1 2 , pero no quiero usar ningún Data Triggers, debido a demasiados estados.
Intenté 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 se produjo un error: los miembros de la colección de desencadenantes deben ser del tipo EventTrigger :(
Como solicitó un ejemplo con datatriggers en los comentarios, aquí está:
Un FrameworkElement solo puede tener EventTriggers, por lo tanto, aparece el mensaje de error. Los activadores de la colección deben ser del tipo EventTrigger
Y tampoco use un ContentPresenter directamente, está destinado a ser utilizado dentro de una plantilla ControlTemplate. Utilice mejor ContentControl cuando desee tener contenido dinámico. Consulte ¿Cuál es la diferencia entre ContentControl y ContentPresenter?
Y finalmente, aquí hay una sugerencia para su problema con DataTrigger. Lo he puesto dentro de un estilo para su 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>
Podría estar equivocado, pero creo que el DataTemplateSelector
solo se usa cuando el ItemContainerGenerator
crea un contenedor para un elemento agregado a la colección. Debido a que no se genera un nuevo contenedor cuando cambia el valor de una propiedad, nunca se aplicará una nueva DataTemplate
a través del selector.
Como se sugiere en los comentarios, le recomendaría que busque en VisualStateManager
o en los activadores de datos, de lo contrario tendrá que volver a crear el contenedor para cada elemento cuando una o más propiedades cambien de valor.
Solo como una opción adicional: si desea atenerse a sus plantillas, simplemente use el enlace s con convertidor.