我正在尝试理解下面的代码是什么 非常满意加载文本文件并显示其内容,但不是满意加载BitmapImage并将其显示在timer.Elapsed事件处理程序上。
我理解它与UI线程有关。
但为什么这不是textfile示例的问题?
首先,XAML:
<Window x:Class="WpfApplication7.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=Message, UpdateSourceTrigger=PropertyChanged}" FontSize="20" Height="40" Width="300" Background="AliceBlue" />
<Image Source="{Binding Path=Image,UpdateSourceTrigger=PropertyChanged}" Height="100" Width="100"/>
</StackPanel>
</Window>
和C#,它在一个计时器上引发了一个PropertyChangedEventHandler:
using System;
using System.ComponentModel;
using System.Timers;
using System.Windows;
using System.IO;
using System.Windows.Threading;
using System.Windows.Media.Imaging;
和
namespace WpfApplication7
{
public partial class Window1 : Window, INotifyPropertyChanged
{
public BitmapImage Image { get; private set; }
public string Message { get; set; }
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private Timer timer;
public Window1()
{
InitializeComponent();
this.DataContext = this;
this.timer = new Timer { Enabled = true, Interval = 100 };
this.timer.Elapsed += (s, e) =>
{
//---happy loading from text file. UI updates :)
this.Message = File.ReadAllText(@"c:\windows\win.ini").Substring(0, 20);
PropertyChanged(this, new PropertyChangedEventArgs("Message"));
//---not happy loading a BitmapImage. PropertyChanged unhappy :(
// (Don't make me have to: ! )
//Application.Current.Dispatcher.Invoke(
//DispatcherPriority.Send, new Action(delegate
//{
this.Image = new BitmapImage(new Uri(@"C:\WINDOWS\Web\Wallpaper\Ascent.jpg"));
//Edit --Ah hah, thanks Daniel !
// DependencyObject-> Freezable-> Animatable->
// ImageSource-> BitmapSource-> BitmapImage
this.Image.Freeze(); //<--- this will fix it, no need for Dispatcher
//Without Dispatcher or Freeze() ... right here:
//"The calling thread cannot access this object because a different thread owns it."
PropertyChanged(this, new PropertyChangedEventArgs("Image"));
//}));
};
}
}
}
我知道我可以用“Application.Current.Dispatcher.Invoke”解决这个问题。所以修复它不是问题。不明白我为什么要这样做是问题:)
类似的问题
答案 0 :(得分:2)
我认为两种情况之间的关键区别在于BitmapImage是一个依赖对象,这意味着它具有“拥有”线程(创建对象的线程)的概念。当你的主UI线程试图访问在另一个线程上创建的(并拥有)的BitmapImage对象时......繁荣!
另一方面,字符串没有“拥有”线程的概念。
答案 1 :(得分:2)
答案 2 :(得分:1)
我认为这是因为BitmapImage是DispatchObject的;您正在非UI线程上创建DispatcherObject,因此是异常。由于文本不是线程对象,因此您看不到文本赋值的错误。