WPF:从另一个线程访问UI元素
问题描述:
尝试执行动画时,获取System.InvalidOperationException(“调用线程无法访问该对象,因为此对象的所有者是另一个线程。”)。WPF:从另一个线程访问UI元素
Thread t = new Thread(new ThreadStart(DoPointsShift));
t.Start();
private void DoPointsShift()
{
int turnsPerMinute = 5;
long delay = 60/turnsPerMinute * 1000/(360/2);
long deltaDelay = delay;
int beginTime = Environment.TickCount;
EasingFunctionBase ease = new CircleEase();
ease.EasingMode = EasingMode.EaseInOut;
while (true)
{
TimeSpan duration = TimeSpan.FromSeconds(1 - 1 * rnd.NextDouble());
foreach (var p in points)
{
var x = p.OriginX - 50 + rnd.NextDouble() * 100;
var y = p.OriginY - 50 + rnd.NextDouble() * 100;
PointAnimation anim = new PointAnimation(new Point(x, y), duration);
anim.EasingFunction = ease;
Dispatcher.BeginInvoke(new Action(() =>
{
p.BeginAnimation(ParallaxPoint.PointCoordProperty, anim); //exception here
}));
}
while (Environment.TickCount - beginTime < delay) { }
delay += deltaDelay;
}
}
有什么想法吗?
答
尝试用包裹函数体:
var dispatcher = Application.Current.Dispatcher;
dispatcher.Invoke((Action)(() =>
{
//your code here
}));
如:
private void DoPointsShift()
{
var dispatcher = Application.Current.Dispatcher;
dispatcher.Invoke((Action)(() =>
{
int turnsPerMinute = 5;
long delay = 60/turnsPerMinute * 1000/(360/2);
long deltaDelay = delay;
int beginTime = Environment.TickCount;
EasingFunctionBase ease = new CircleEase();
ease.EasingMode = EasingMode.EaseInOut;
while (true)
{
TimeSpan duration = TimeSpan.FromSeconds(1 - 1 * rnd.NextDouble());
foreach (var p in points)
{
var x = p.OriginX - 50 + rnd.NextDouble() * 100;
var y = p.OriginY - 50 + rnd.NextDouble() * 100;
PointAnimation anim = new PointAnimation(new Point(x, y), duration);
anim.EasingFunction = ease;
Dispatcher.BeginInvoke(new Action(() =>
{
p.BeginAnimation(ParallaxPoint.PointCoordProperty, anim); //exception here
}));
}
while (Environment.TickCount - beginTime < delay) { }
delay += deltaDelay;
}
}));
}
杰夫
你必须CAL开始从UI线程,而不是backgrond线程动画 – Viru