我一直试图弄清楚这个问题已经有一段时间了,我只是难倒了。我创建了一个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具有响应性,而不是“锁定”。我想我可以在控件渲染到屏幕而不是一次全部时错开,因为那将是视图的主要瓶颈。
答案 0 :(得分:0)
编辑: 如果您确实在使用MVVM模式,则应在主(UI)线程上创建控件,在另一个线程上创建对象数据,并在控件的DataContext可用时将其设置为控件的DataContext。更好的是,在每个'DataContext'变得可用之前,不要创建控件。这是保持应用程序响应的常用方法,即使您可能需要等待很长时间才能获得数据,例如通过互联网。
OLD - &gt;关于你问题的第一部分: 这不是一个线程问题。简而言之,这是行不通的,因为当您尝试反序列化数据时,运行时会尝试再次将模板添加到对象的内部“XAMLType”表示中。此效果不仅限于模板,但是,当您尝试以这种方式加载时,您定义的任何资源都会导致问题。即使给控件中的XAML元素赋予名称等也会产生问题。
编辑: 您尝试使用的XAML序列化程序方法不是它的目的。此外,由于您在评论中提到的原因,您不希望在另一个线程上创建控件。