WPF多级绑定线程问题

时间:2014-07-30 12:11:04

标签: c# .net wpf multithreading binding

刚刚发现了一个有趣的WPF问题我可以真正使用你的帮助:我有一个多级绑定Binding="{Binding PreviewItem.Status},当且仅当属性从后台线程更新时才会产生奇怪的行为。我使用了diagnostics:PresentationTraceSources.TraceLevel=High,似乎发生的情况是,如果状态更新,它会阻止绑定在它之后的瞬间实现整个PreviewItem更改!

我设法在一个新的空C#测试项目(VS 2012,.NET 4.5)中重现行为。这是主要代码:channel和TimelineItem都是空类,只有一个属性具有所有正确的notifypropertychanged事件通知,StatusType是一个枚举,控件的DataContext设置为_channel

Task.Run(() =>
        {
            if ( _channel.PreviewItem != null )
            {
                _channel.PreviewItem.Status = TimelineItem.StatusType.Default;
            }
            _channel.PreviewItem = new TimelineItem();
            _channel.PreviewItem.Status = TimelineItem.StatusType.Preview;
        });
}

让我们说我们这样做了三次以创造三个项目:

  1. 创建A并将其分配给PreviewItem,A'状态转到"预览" (OK)
  2. A的状态变为Default,B被创建并分配给PreviewItem(失败,绑定仍然使用A,当状态改变时,更新到新状态,永远不会重新绑定到B!)
  3. B&#39>的状态变为默认,C被创建并分配给PreviewItem(确定为A的状态 - 其中绑定仍然被解析为 - 不会改变,因此它注意到PreviewItem已更改为C)
  4. 如果我a)将完全相同的代码移动到主线程或b)分配新的PreviewItem,在更改旧项目状态之前,代码可以正常工作!不幸的是,我不能在我的项目中使用这两种方法。

    任何人都知道为什么这不起作用?据我所知,WPF应该负责将更改事件发送给适当的调度程序。任何帮助都非常感谢...

    亚历

    更新2014年8月4日#

    出于某种奇怪的原因,错误行为只发生在Windows 7上。整个项目可以是found here

    更新2014年9月2日

    问题已通过修补程序解决:http://support.microsoft.com/kb/2783808/en-us

2 个答案:

答案 0 :(得分:0)

在WPF中,只有创建UI(控件)的线程才能访问\修改该对象。例如,从主UI线程启动的后台线程无法更新在UI线程上创建的任何控件的内容。

您需要重新调用UI线程,有多种方法可以做到这一点,以下是最简单的方法之一:

Application.Current.Dispatcher.Invoke(() => 
{
    // your GUI related code here
});

答案 1 :(得分:0)

您可以将.Net版本更新为4.5.1 / 4.5.2并重新检查吗?这可能是最近更新中可能已修复的错误。我只在Windows 7机器上检查了你的代码并且无法重现它,所以它与框架版本有关。