我有一个WPF图像控件,其源属性绑定到一个属性" ImageSrc"返回一个Image对象。
<Window x:Class="My.Apps.WPF.Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewmodel="clr-namespace:My.Apps.WPF.ViewModels"
xmlns:classes="clr-namespace:My.Apps.WPF.Classes"
>
<Window.Resources>
<viewmodel:MyViewModel x:Key="myViewModel" />
<classes:ImgToSrcConverter x:Key="imgToSrcConverter" />
</Window.Resources>
<Grid x:Name="TopGrid" DataContext="{StaticResource myViewModel}">
<Image Grid.Row="0">
<Image.Source>
<MultiBinding NotifyOnTargetUpdated="True" Converter="{StaticResource imgToSrcConverter}">
<Binding Path="ImageSrc" />
<Binding Path="." />
</MultiBinding>
</Image.Source>
</Image>
</Grid>
</Window>
转换器:
public class ImgToSrcConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
Image image = values[0] as Image;
if (image != null)
{
MemoryStream ms = new MemoryStream();
image.Save(ms, image.RawFormat);
ms.Seek(0, SeekOrigin.Begin);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
ViewModel vm = values[1] as ViewModel;
bi.DownloadCompleted += (s, e) =>
{
vm.Method();
};
return bi;
}
return null;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我遇到的问题是BitmapImage的DownloadCompleted事件永远不会被提升,所以行:
vm.Method();
永远不会被执行,因此我的视图模型中的Method()永远不会被执行。
我在使用视图模型中绑定的ImageSrc属性从视图中的Image对象更新Source属性时检查了转换器是否正确执行。
我做错了什么?
答案 0 :(得分:1)
我找到了一种方法来做到这一点虽然不是最好的方法,但我一整天都在努力解决绑定触发器和图像和流的可用方法。我最终做的是分配一个全局布尔值,说明图像已被更改,然后使用Image.LayoutUpdated操作来检查该布尔值。一旦它看到布尔值并验证图像大小不为零,它就会反转布尔值(因此它不会再次运行)并执行需要在图像加载/视图中完成的操作。
答案 1 :(得分:0)
查看BitmapImage
DownloadCompleted
活动documentation,备注部分:
可能不会针对所有类型的位图内容引发此事件。
答案 2 :(得分:0)
由于在从流中创建BitmapImage时未进行下载,因此未触发DownloadCompleted事件。
您不应该通过绑定转换器执行此操作,而是使用另一个具有异步绑定的ImageSource类型的视图模型属性。
private ImageSource imageSource;
public ImageSource ImageSource
{
get
{
if (imageSource == null)
{
using (var stream = new MemoryStream())
{
...
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
bitmap.Freeze(); // necessary for async binding
imageSource = bitmap;
}
Method();
}
return imageSource;
}
}
然后像这样绑定到这个属性:
<Image Source="{Binding ImageSource, IsAsync=True}"/>
您也可以使用少量代码创建一个BitmapFrame,而不是BitmapImage:
private ImageSource imageSource;
public ImageSource ImageSource
{
get
{
if (imageSource == null)
{
using (var stream = new MemoryStream())
{
...
imageSource = BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
Method();
}
return imageSource;
}
}
答案 3 :(得分:0)
DownloadCompleted 事件没有被触发,我遇到了类似的问题。 在我用类中的 BitmapImage 属性替换了方法中的局部变量之后。 事件再次被触发。 可能是垃圾收集器,收集了参考。