¿Cómo puedo reemplazar una imagen en una cuadrícula de WPF con otro control dependiendo de los datos de origen?

StackOverflow https://stackoverflow.com/questions/424562

  •  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.

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top