如何在两个线程之间正确传递包含资源的UserControl?

时间:2011-02-02 14:56:50

标签: c# wpf xaml serialization user-controls

我一直试图弄清楚这个问题已经有一段时间了,我只是难倒了。我创建了一个UserControl类型(在下面编辑),我试图从后台线程生成和序列化。

生成Control的后台线程被标记为STA并使用内存流来传递控件。但是,该控件包含UserControl.Resources部分中的数据模板,该模板在反序列化期间导致错误。

在没有在外部合并资源字典中定义资源的情况下,是否无法在线程之间传递包含资源的用户控件?

代码: 用户控件:

<UserControl x:Class="WPF_Base.Example">
 <UserControl.Resources>
   <DataTemplate DataType={x:Type Example2}>
     <Example2View />
   </DataTemplate>
 </UserControl.Resources>
 <Grid>
  <StackPanel>
   <ItemsControl ItemSource="{Binding GetExamples}" />
  </StackPanel>
 </Grid>
</UserControl>

ThreadCode(作为单个线程提供):

            System.IO.MemoryStream streamer = new System.IO.MemoryStream();

            var testExample = new WPF_Base.Example();
            var test = System.Windows.Markup.XamlWriter.Save(testExample);

            var test2 = new System.IO.StringReader(test);
            var test3 = System.Xml.XmlReader.Create(test2);
            var test4 = (WPF_Base.TestExample)System.Windows.Markup.XamlReader.Load(test3); //Exception thrown here about key already existing in the dictionary

编辑:    控件正在另一个线程中生成和构建,因为用户可能正在加载包含许多数据(控件是MVVM模式)的文件,每个文件都表示为屏幕上的视图。在此过程中,我仍然希望UI具有响应性,而不是“锁定”。我想我可以在控件渲染到屏幕而不是一次全部时错开,因为那将是视图的主要瓶颈。

1 个答案:

答案 0 :(得分:0)

编辑: 如果您确实在使用MVVM模式,则应在主(UI)线程上创建控件,在另一个线程上创建对象数据,并在控件的DataContext可用时将其设置为控件的DataContext。更好的是,在每个'DataContext'变得可用之前,不要创建控件。这是保持应用程序响应的常用方法,即使您可能需要等待很长时间才能获得数据,例如通过互联网。

OLD - &gt;关于你问题的第一部分: 这不是一个线程问题。简而言之,这是行不通的,因为当您尝试反序列化数据时,运行时会尝试再次将模板添加到对象的内部“XAMLType”表示中。此效果不仅限于模板,但是,当您尝试以这种方式加载时,您定义的任何资源都会导致问题。即使给控件中的XAML元素赋予名称等也会产生问题。

编辑: 您尝试使用的XAML序列化程序方法不是它的目的。此外,由于您在评论中提到的原因,您不希望在另一个线程上创建控件。