WPF The calling thread cannot access this object because a different thread owns it.
public int ImgIdx { get { return imgIdx; } set { if(value!=imgIdx) { imgIdx = value; if(imgIdx<0) { imgIdx = imgsCount - 1; } if(imgIdx>=imgsCount) { imgIdx = 0; } OnPropertyChanged(nameof(ImgIdx)); if(!isPaused) { ImgUrl = imgsList[ImgIdx]; Title = ImgUrl; } } } }
System.InvalidOperationException
HResult=0x80131509
Message=The calling thread cannot access this object because a different thread owns it.
Source=WindowsBase
StackTrace:
at System.Windows.Threading.Dispatcher.VerifyAccess()
at System.Windows.Window.set_Title(String value)
at WpfApp219.MainWindow.set_ImgIdx(Int32 value) in D:\C\WpfApp219\MainWindow.xaml.cs:line 77
at WpfApp219.MainWindow.Tmr_Elapsed(Object sender, ElapsedEventArgs e) in D:\C\WpfApp219\MainWindow.xaml.cs:line 104
at System.Timers.Timer.MyTimerCallback(Object state)
public int ImgIdx { get { return imgIdx; } set { if(value!=imgIdx) { imgIdx = value; if(imgIdx<0) { imgIdx = imgsCount - 1; } if(imgIdx>=imgsCount) { imgIdx = 0; } OnPropertyChanged(nameof(ImgIdx)); if(!isPaused) { Application.Current.Dispatcher.BeginInvoke(new Action(() => { ImgUrl = imgsList[ImgIdx]; Title = ImgUrl; })); } } } }
Application.Current.Dispatcher.BeginInvoke(new Action(() => { ImgUrl = imgsList[ImgIdx]; Title = ImgUrl; }));
//xaml <Window x:Class="WpfApp219.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:WpfApp219" mc:Ignorable="d" KeyDown="Window_KeyDown" WindowState="Maximized" Title="MainWindow" Height="450" Width="800"> <Grid> <Image x:Name="img" Source="{Binding ImgUrl,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" MouseWheel="img_MouseWheel" MouseDown="img_MouseDown" MouseUp="img_MouseUp" MouseMove="img_MouseMove"> <Image.RenderTransform> <TransformGroup> <ScaleTransform x:Name="scaler"/> <TranslateTransform x:Name="translater"/> </TransformGroup> </Image.RenderTransform> </Image> </Grid> </Window> //cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.IO; namespace WpfApp219 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propName) { var handler = PropertyChanged; if (handler != null) { handler?.Invoke(this, new PropertyChangedEventArgs(propName)); } } private string imgUrl; public string ImgUrl { get { return imgUrl; } set { if (value != imgUrl) { imgUrl = value; OnPropertyChanged(nameof(ImgUrl)); //this.Title = imgUrl; } } } private int imgIdx = 0; public int ImgIdx { get { return imgIdx; } set { if(value!=imgIdx) { imgIdx = value; if (imgIdx < 0) { imgIdx = imgsCount - 1; } if (imgIdx >= imgsCount) { imgIdx = 0; } OnPropertyChanged(nameof(ImgIdx)); if (!isPaused) { Application.Current.Dispatcher.BeginInvoke(new Action(() => { ImgUrl = imgsList[ImgIdx]; Title = ImgUrl; ResetTransform(); })); } } } } private List<string> imgsList { get; set; } private int imgsCount = 0; private bool isPaused = false; private Point currentPt { get; set; } private bool isMoving = false; public MainWindow() { InitializeComponent(); imgsList = new List<string>(Directory.GetFiles(@"..\..\Images")); imgsCount = imgsList.Count; ImgUrl = imgsList[imgIdx]; this.DataContext = this; System.Timers.Timer tmr = new System.Timers.Timer(); tmr.Interval = 300; tmr.Elapsed += Tmr_Elapsed; tmr.Start(); } private void Tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { ++ImgIdx; } private void ResetTransform() { scaler.ScaleX = 1.0; scaler.ScaleY = 1.0; scaler.CenterX = 0; scaler.CenterY = 0; translater.X = 0; translater.Y = 0; } private void img_MouseWheel(object sender, MouseWheelEventArgs e) { if (e.Delta > 0) { scaler.ScaleX *= 1.2; scaler.ScaleY *= 1.2; } else { scaler.ScaleX /= 1.2; scaler.ScaleY /= 1.2; } scaler.CenterX = e.GetPosition(img).X; scaler.CenterY = e.GetPosition(img).Y; } private void img_MouseDown(object sender, MouseButtonEventArgs e) { currentPt = e.GetPosition(img); } private void img_MouseUp(object sender, MouseButtonEventArgs e) { if(e.ChangedButton==MouseButton.Left && e.ButtonState==MouseButtonState.Released && isMoving) { Point newPt = e.GetPosition(img); translater.X += (newPt.X - currentPt.X) * scaler.ScaleX; translater.Y += (newPt.Y - currentPt.Y) * scaler.ScaleY; } } private void img_MouseMove(object sender, MouseEventArgs e) { isMoving = true; } private void Window_KeyDown(object sender, KeyEventArgs e) { if(e.Key==Key.Down) { ++ImgIdx; } else if ((e.Key == Key.Up)) { --ImgIdx; } else if(e.Key==Key.Space) { isPaused=!isPaused; } } } }