WPF通过转换器将图像列绑定到数据网格中,不能在属性更改时更新图像
本文关键字:图像 不能 属性 网格 更新 数据网 转换器 数据 绑定 WPF | 更新日期: 2023-09-27 18:13:30
我有一个数据网格,它被绑定到一个可观察的项目集合,如下所示:
<DataGrid ItemsSource="{Binding Path=MyItems}">
然后,其中一列通过一个简单的转换器绑定到MyItems的属性,该转换器将bool值转换为图像路径。
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Name="DownloadedIcon" Source="{Binding Converter={StaticResource BoolToImageCheckmark}, ConverterParameter=IsDownloaded, UpdateSourceTrigger=PropertyChanged}" Width="16" Height="16" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
属性本身isdownload完全实现了INotifyPropertyChanged。
这正常工作,因为显示的数据与集合的值相匹配,并且图像列根据属性值正确显示图像。
当属性改变时麻烦来了。如果我直接在属性上绑定一个文本列,那么当属性更新时,内容也会更新。但是,经过转换器的图像列将不会收到更新通知。
任何想法?
试试这个:
<DataTemplate>
<Image Name="DownloadedIcon" Source="{Binding Path=IsDownloaded,Converter={StaticResource BoolToImageCheckmark}}" Width="16" Height="16" />
</DataTemplate>
还要在转换器中放置一个断点,以便验证绑定是否实际工作。注意,您将通过转换器中的Value
参数获得绑定值。
传递给ConverterParameter的值不会对PropertyChanged通知作出反应。在绑定中使用Path而不是ConverterParameter,然后在转换器中引用Convert()函数中的value参数,而不是parameter参数。
ConverterParameter
不是一个依赖属性,因此您不能像尝试那样将它绑定到一个属性。你应该将你的图像源绑定到IsDownloaded
属性并转换为:
<DataTemplate>
<Image Name="DownloadedIcon" Source="{Binding Path=IsDownloaded,Converter={StaticResource BoolToImageCheckmark}}" Width="16" Height="16" />
</DataTemplate>
问题出在您的转换器类中。
由于绑定表达式没有指定"Path",所以使用当前DataContext作为路径,并在DataContext对象中作为转换器类中的值。计算正在这个数据上下文对象的副本上执行。
此方法将在绑定执行时第一次成功。因此,图像列正确地显示了图像。
后来' isdownloads '属性发生了变化,它反映在ObservableCollectionClass中,但是图像控件无法理解这个变化,因为它的源属性没有绑定到任何集合类属性。与转换器类接收数据上下文对象的副本类似,属性更改也不会反映在转换器类中。
因此,将图像源属性设置为集合类属性' isdownloads '。此属性发生的任何更改都将触发具有新值的转换器类。
不需要UpdateSourceTrigger
事实上,您没有将图像绑定到属性isdownloads您将其绑定到列表中的整个对象。
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Name="DownloadedIcon" Source="{Binding Converter={StaticResource BoolToImageCheckmark}, ConverterParameter=IsDownloaded, Path=IsDownloaded, UpdateSourceTrigger=PropertyChanged}" Width="16" Height="16" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>