如何根据源数据将 WPF 网格中的图像替换为另一个控件?

发布于 2024-07-12 10:48:44 字数 1369 浏览 7 评论 0原文

我有一个像这样布置的网格;

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

这一切都运行良好,但我现在想将图像更改为另一组控件,当列表视图中的所选项目没有图像时,显示“抱歉,没有可用的图像”

我尝试将图像包装在 DockPanel 中,并且在那里设置一个 DataTemplate(这样我就可以使用 DataTriggers),但 IntelliSense 说不!

ListView 使用 DataTriggers 来做类似的事情,但正如我所说,我无法理解如何对似乎无法访问 DataTemplate 的单个图像执行此操作。

简化的 XAML 如下;

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

提前感谢 WPF 专家。

Ryan

更新:下面的两个答案(Abe 和 Jobi)都很正确,谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

木格 2024-07-19 10:48:44

为了使用 DataTemplate,您必须有一个使用该模板来呈现对象的控件。 如果您使用 ContentPresenter,则可以将其 ContentTemplate 设置为您喜欢的任何数据模板。

我将这样做:

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

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>
翻身的咸鱼 2024-07-19 10:48:44

如果您不关心 WPF 视觉树中创建的视觉效果,您可以在这里做一个简单的技巧。
只需将图像控件放在“不可用”控件的顶部,以便在任何时候图像加载失败时,您都可以看到以下消息。 如果图像控制成功,则“不可用”消息将与图像重叠。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文