如何使用TaskFactory创建新的UI元素?当我尝试时,我会得到以下错误:
调用线程必须是STA,因为许多UI组件都需要这个.。
示例代码
Dim txtBoxList as new List(Of TextBox)
Sub StartThread()
Dim TS As TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext()
Task.Factory.StartNew(Sub() CreateControl(), TS)
End Sub
Sub CreateControl()
Dim txtBox As New TextBox
Dispatcher.BeginInvoke(Sub() txtBoxList.Add(txtBox))
End Sub发布于 2014-04-25 23:23:53
如果您正在使用WPF,那么您确实需要抛弃您可能从古老的技术中学到的任何和所有的概念,并理解和接受The WPF Mentality。
基本上,您几乎不需要在WPF中的过程代码中创建或操作UI元素。相反,WPF允许自己大量使用DataBinding。
The WPF Threading Model to not允许您在后台线程中创建或操作UI元素的实例,并将它们添加到由“主”UI线程创建的Visual Tree中。
无论如何,这样的事情几乎是零需要的,因为在大多数情况下,创建UI元素是一项琐碎的任务,可以(而且必须)由UI线程执行。
与其担心Visual,不如将数据加载到后台线程中,然后作为DataContext传递给UI,以便它能够相应地显示数据。
这是一个小示例,它使用ItemsControl来显示用户列表,这些用户被异步加载在后台线程中,然后被分派到UI线程以供显示:
<Window x:Class="WpfApplication7.AsyncItemsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="LightGray" BorderBrush="Black" BorderThickness="1" Margin="2">
<StackPanel>
<TextBlock Text="{Binding LastName}" Margin="2"/>
<TextBlock Text="{Binding FirstName}" Margin="2"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>代码背后:
public partial class AsyncItemsControl : Window
{
public AsyncItemsControl()
{
InitializeComponent();
var dispatcher = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() => GetUsers())
.ContinueWith(x => DataContext = x.Result,dispatcher);
}
public List<User> GetUsers()
{
// pretend this method calls a Web Service or Database to retrieve the data, and it takes 5 seconds to get a response:
Thread.Sleep(5000);
return new List<User>
{
new User() {FirstName = "Marty", LastName = "McFly"},
new User() {FirstName = "Emmett", LastName = "Brown"},
new User() {FirstName = "Bufford", LastName = "Tannen"}
};
}
}数据项:
public class User
{
public string LastName { get; set; }
public string FirstName { get; set; }
}结果:

string属性的简单User类操作。ItemsControl是如何创建和呈现显示3个数据项所需的批准UI元素的。“每个项目的外观”的实际定义是DataTemplate。Task的内容来利用async / await并使代码更简洁。我在C# 4.0上,所以这个特性对我来说是不可用的。File -> New Project -> WPF Application中,并亲自查看结果。https://stackoverflow.com/questions/23303985
复制相似问题