views:

672

answers:

2

I have a grid laid out like so;

+---------+---------+
|  Image  | Details |
|    is   |  pane   |
|  here   | for data|
|         |  entry  |
+---------+---------+
| ListView here to  |
| select data item  |
| for top two panes |
+---------+---------+

This all works well, but I would now like to change the image to another set of controls saying 'Sorry, no image available' when the selected item in the listview does not have an image

I've tried wrapping the image in a DockPanel and setting a DataTemplate there (so I can use DataTriggers) but IntelliSense says no!

The ListView uses DataTriggers to do a similar thing, but as I say I can't get my head round how to do it for a single image that does not seem to have access to a DataTemplate.

Simplified XAML is below;

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

Thanks in advance WPF gurus.

Ryan

Update: Both answers below (Abe and Jobi) were spot on, thanks.

+3  A: 

In order to use a DataTemplate, you have to have a control that uses the template to render an object. If you use a ContentPresenter, you can set its ContentTemplate to be a DataTemplate to whatever you like.

Here is how I would do this:

<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>
Abe Heidebrecht
+2  A: 

You can do an easy trick here, if you are not concerned about the visuals get created in the WPF visual tree. Just place the Image control on top of the 'Not available' control so that at any time Image load gets failed you would be able to see the bellow message. If image control succeeded then 'Not available' message get overlapped by the image.

Jobi Joy