J'essaie de comprendre ce qu'il est sur le code suivant qui est parfaitement heureux avec le chargement d'un fichier texte et d'afficher son contenu, mais n'est pas content de charger un BitmapImage et de l'afficher sur un gestionnaire d'événement timer.Elapsed. Je comprends que cela a à voir avec le thread de l'interface utilisateur.WPF événement: BitmapImage PropertyChanged: « L'appel de cette discussion ne peut pas accéder »
Mais pourquoi cela ne pose-t-il pas un problème pour l'exemple textfile?
D'abord, le 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>
et C#, ce qui soulève un PropertyChangedEventHandler sur une minuterie:
using System;
using System.ComponentModel;
using System.Timers;
using System.Windows;
using System.IO;
using System.Windows.Threading;
using System.Windows.Media.Imaging;
et
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"));
//}));
};
}
}
}
Je sais que je peux résoudre ce problème avec un "Application.Current.Dispatcher.Invoke". Donc, la réparation n'est pas le problème. Ne pas comprendre pourquoi je dois est le problème :)
similaires aux questions
Merci Daniel cela m'a vraiment aidé à comprendre la racine du problème. –