0

I have a WPF application that is utilizing the reporting tools included with Visual Studio 2010. I've had some other problems that I've solved by creating a graph of objects that are all marked as serializable, etc., as mentioned on various other web pages.

The ReportViewer control is contained in a WindowsFormsHost. I'm handling the SubreportProcessing event of the ReportViewer.LocalReport object to provide the data for the sub report.

The object graph that I'm reporting on is generated in my viewmodel, and that viewmodel holds a reference to it. The SubreportProcessing handler is in my code behind of my window (may not be the best place - but I simply want to get the ReportViewer working at this point).

Here's the problem: In my event handler, I'm attempting to get a reference to my viewmodel using the following code:

var vm = DataContext as FailedAssemblyReportViewModel;

When the handler is called, this line throws an InvalidOperationException with the message The calling thread cannot access this object because a different thread owns it.

I didn't realize the handler might be called on a different thread. How can I resolve this?

I attempted some searches, but all I've come up with is in regards to updating the UI from another thread using the Dispatcher, but that won't work in this case...

4

2 回答 2

0

我通过添加以下函数使用我认为是 hack 的方法解决了这个问题:

public object GetDataContext() {
    return DataContext;
}

然后将我的问题中的代码行替换为:

object dc = Dispatcher.Invoke(new Func<object>(GetDataContext), null);
var vm = dc as FailedAssemblyReportViewModel;

但是,这似乎是一种 hack,我可能会绕过 CLR 正在执行的某种安全检查。请让我知道这是否是一种不正确的方法来实现这一点。

于 2013-06-17T13:19:24.090 回答
0

这是一个令人讨厌的问题。为什么不在视图中使用绑定到 Windows 窗体主机的内容演示器?在视图模型中,您将拥有类型为 WindowsFormsHost 的属性。此外,在视图模型的构造函数中,您可以使用报表查看器设置 Windows 窗体的主机子属性。之后一帆风顺,您可以在代码中的任何位置使用报表查看器。像这样的东西:查看:

<ContentPresenter Content="{Binding Path=FormHost}"/>                        

视图模型:

private ReportViewer report = new ReportViewer();
private WindowsFormsHost host = new WindowsFormsHost();
public WindowsFormsHost FormHost
{
 get {return this.host;}
 set
     {
      if(this.host!=value)
      {
      this.host = value;
      OnPropertyChanged("FormHost");
      }
     }
}


public ViewModel() //constructor
{
     this.host.Child = this.report;
}

在那愉快的编码之后。希望能帮助到你。

于 2013-06-17T13:23:14.757 回答