¿Cómo puedo reemplazar una imagen en una cuadrícula de WPF con otro control dependiendo de los datos de origen?
-
05-07-2019 - |
Pregunta
Tengo una cuadrícula dispuesta como tal;
+---------+---------+
| Image | Details |
| is | pane |
| here | for data|
| | entry |
+---------+---------+
| ListView here to |
| select data item |
| for top two panes |
+---------+---------+
Todo esto funciona bien, pero ahora me gustaría cambiar la imagen a otro conjunto de controles que dice 'Lo siento, no hay imagen disponible' cuando el elemento seleccionado en la vista de lista no tiene una imagen
He intentado envolver la imagen en un DockPanel y establecer una DataTemplate allí (para poder usar DataTriggers), ¡pero IntelliSense dice que no!
El ListView usa Data Triggers para hacer algo similar, pero como digo, no puedo entender cómo hacerlo para una sola imagen que no parece tener acceso a una DataTemplate.
El XAML simplificado está debajo;
<Grid DataContext="{Binding Source={StaticResource MyData}}">
<!-- row 0 col 0 -->
<Image x:Name="imgPhoto" Source="{Binding ElementName=MyListViewOfData, Path=SelectedItem.PathToImageOnDisk}" />
<!-- row 0 col 1 -->
<StackPanel DataContext="{Binding ElementName=MyListViewOfData, Path=SelectedItem}">
<TextBox Name="NameTextBox" Text="{Binding Name}" />
<TextBlock Name="DateCreatedTextBlock" Text="{Binding DateCreated}" />
</StackPanel>
<!-- row 1 cols 0,1 -->
<ListView ItemsSource="{Binding}" ItemTemplate="{StaticResource MyListViewTemplate}"
IsSynchronizedWithCurrentItem="True" Name="MyListViewOfData" />
</Grid>
Gracias de antemano a los gurús de WPF.
Ryan
Actualización: las dos respuestas a continuación (Abe y Jobi) fueron acertadas, gracias.
Solución
Para usar un DataTemplate, debes tener un control que use la plantilla para representar un objeto. Si usa un ContentPresenter, puede configurar su ContentTemplate para que sea una DataTemplate como desee.
Aquí es cómo haría esto:
<Grid DataContext="...">
<ContentPresenter Content="{Binding SelectedItem, ElementName=MyListViewOfData}">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image x:Name="imgPhoto" Source="{Binding PathToImageOnDisk}" />
<TextBlock x:Name="error" Visibility="Collapsed" Text="Sorry, no image available" />
<StackPanel Grid.Column="1">
<TextBox Name="NameTextBox" Text="{Binding Name}" />
<TextBlock Name="DateCreatedTextBlock" Text="{Binding DateCreated}" />
</StackPanel>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding PathToImageOnDisk}" Value="{x:Null}">
<Setter TargetName="imgPhoto" Property="Visibility" Value="Collapsed" />
<Setter TargetName="error" Property="Visibility" Value="Visible" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
<ListView ItemsSource="{Binding}" ItemTemplate="{StaticResource MyListViewTemplate}" IsSynchronizedWithCurrentItem="True" Name="MyListViewOfData" />
</Grid>
Otros consejos
Puede hacer un truco fácil aquí, si no está preocupado por los elementos visuales que se crean en el árbol visual de WPF. Simplemente coloque el control de imagen sobre el control 'No disponible' para que, en cualquier momento, la carga de imágenes falle, pueda ver el siguiente mensaje. Si el control de la imagen tuvo éxito, el mensaje 'No disponible' se superpondrá con la imagen.