Ich versuche zu verstehen, was es zu folgendem Code ist, dass ist vollkommen glücklich mit einer Textdatei laden und dessen Inhalt angezeigt wird, aber ist nicht zufrieden mit dem Laden eines BitmapImage und dessen Anzeige auf einem Timer.Elapsed-Ereignishandler.WPF Ereignis: Bitmapproperty: „Calling Thread kann nicht zugreifen“
Ich verstehe, dass es mit dem UI-Thread zu tun hat.
Aber warum ist das kein Problem für das Textdateibeispiel?
Erstens, die 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>
und die C#, das eine PropertyChangedEventHandler auf einem Timer erhöht:
using System;
using System.ComponentModel;
using System.Timers;
using System.Windows;
using System.IO;
using System.Windows.Threading;
using System.Windows.Media.Imaging;
und
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"));
//}));
};
}
}
}
Ich weiß, ich kann dieses Problem beheben mit ein "Application.Current.Dispatcher.Invoke". Also ist es nicht das Problem, es zu reparieren. Nicht zu verstehen, warum muß ich soll das Problem ist :)
ähnliche Fragen
Daniel danke das hat mir wirklich geholfen, die Wurzel des Problems zu verstehen. –