界面绑定了一个图片:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
x:Name="main"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="Window1" Height="300" Width="300">
<Grid>
<Image x:Name="image" Source="{Binding ImageSource1}"></Image>
</Grid>
</Window>
这个图片绑定的属性源:
private BitmapImage imageSource1;
public BitmapImage ImageSource1
{
get
{
return imageSource1;
}
set
{
imageSource1 = value;
if (null != PropertyChanged)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs("ImageSource1"));
}
}
}
为了演示内存没被释放 ,用一个在MainWindow上的按钮来弹出上面的Window1界面:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Width="75" Click="button_Click"/>
</Grid>
</Window>
private void button_Click(object sender, RoutedEventArgs e)
{
BitmapImage imageSource1 = new BitmapImage();
imageSource1.BeginInit();
imageSource1.CacheOption = BitmapCacheOption.OnLoad;
imageSource1.StreamSource = new MemoryStream(File.ReadAllBytes("TestImage.png"));
imageSource1.EndInit();
Window1 w1 = new Window1();
w1.ImageSource1 = imageSource1;
w1.ShowDialog();
//BindingOperations.ClearBinding(w1.image, System.Windows.Controls.Image.SourceProperty);
}
在没关闭Window1界面的时候,内存里是有 Window1 这个实例的:

当我关闭Window1界面的时候,内存里是还是有 Window1 这个实例的,显然Window1 没被释放掉:

找了很久,发现原来是图片一直占用着绑定资源,直到我手动加上最后一句:
private void button_Click(object sender, RoutedEventArgs e)
{
BitmapImage imageSource1 = new BitmapImage();
imageSource1.BeginInit();
imageSource1.CacheOption = BitmapCacheOption.OnLoad;
imageSource1.StreamSource = new MemoryStream(File.ReadAllBytes("TestImage.png"));
imageSource1.EndInit();
Window1 w1 = new Window1();
w1.ImageSource1 = imageSource1;
w1.ShowDialog();
BindingOperations.ClearBinding(w1.image, System.Windows.Controls.Image.SourceProperty);
}
内存就被释放掉了:
但是用这句就不能释放,存留疑问:
BindingOperations.ClearAllBindings(w1);
有人说换图片数据源,不要这么赋值,我也试过了,从一个文件直接绑定图片,是可以释放掉的,但是项目里是从硬件里copy过来byte[]转换成的图片, 上面的只是我为了演示,暂时从图片文件里获取。
最后,我就是想知道有没有其它方法能够释放掉上面的图片绑定,我不想给界面控件赋上一个x:Name="xxx" ,然后再用下面的方式去解绑BindingOperations.ClearBinding(w1.xxx, System.Windows.Controls.Image.SourceProperty)
显然不符MVVM的风格,ViewModel里还有各种页面控件,看起来就很乱,有没有其它能从属性源头解绑的方式?或者其它更好的解绑做法?
谢谢 老哥们了~