我正在开发一个Windows窗体,它将采用用户的经纬度,执行一些长时间的计算并在地图上显示用户的位置和一些路线。该地图将使用Bing地图API在单独的WPF窗口中显示。由于在用户输入经纬度后需要执行的计算很复杂,需要花费很多时间,因此我需要在后台线程中执行这些计算并从后台线程调用新的WPF窗口。正在从Winform调用Bing Map的WPF窗口
起初,由于线程关联性,我无法从后台线程打开WPF窗口,但是在将线程的公寓状态设置为ApartmentState.STA
之后,我对其进行了修复。这里是用户输入经纬度和后压上的按钮在WinForm的被调用的程序:
private void button1_Click(object sender, EventArgs e)
{
Thread t1 = new Thread(foo);
t1.SetApartmentState(ApartmentState.STA);
t1.IsBackground = true;
t1.Start();
}
线程启动时被执行的过程foo()
。我已阅读,我需要调用System.Windows.Threading.Dispatcher.Run()
论坛,使WPF窗口不会立即关闭的线程完成:
private void foo()
{
MainWindow window = new MainWindow(lat.Text, lon.Text);
window.Show();
window.Closed += (sender2, e2) => window.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run();
}
WPF窗口称为主窗口。下面是它的代码:
public partial class MainWindow : Window
{
public MainWindow(double latitude, double longitude)
{
InitializeComponent();
myMap123.Focus();
//Set the map mode to Aerial with labels
myMap123.Mode = new AerialMode(true);
}
}
最后,如果一些你需要的WPF窗口的XAML文件,那就是:
<Window x:Class="WPFTestApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF"
Title="MainWindow" Height="350" Width="525">
<Grid>
<m:Map CredentialsProvider="KEY" x:Name="myMap123"/>
</Grid>
</Window>
当我输入一些纬度和经度,然后按一下按钮, WPF窗口确实出现,但Bing Map不显示世界地图。相反,背景是灰色的,如果我尝试缩放或更改窗口的大小,则会引发System.NullReferenceException
(对象引用未设置为对象的实例)。调试器告诉我,异常引发线System.Windows.Threading.Dispatcher.Run();
。但是,如果我不尝试将地图居中并且不将地图设置为“空中”模式,则一切正常。我应该怎么做才能从后台线程调用WPF窗口并在运行时更改Bing Map的属性,而不会有任何问题? 我已经检查过,如果WPF窗口从主UI线程被调用,那么一切都会正常工作。 有趣的是,如果我关闭WPF窗口并再次按下按钮,新的WPF窗口通常会显示Bing地图,并且不会抛出System.NullReferenceException
。
为什么要在新线程中显示新窗口?为什么不在创建新窗口时通过Dispatcher调用回主WPF UI线程? – 2014-10-28 19:50:30
好吧,主线程如何知道后台线程何时完成其计算?这不需要用户在后台线程完成后按下其他按钮来显示地图吗? – user3623874 2014-10-28 19:53:34
这取决于Map对象。但最坏的情况是,您在后台线程上运行“计算”操作(即通过任务),然后在操作完成时使用Dispatcher.Invoke()通知主线程。不幸的是,你的代码示例实际上并没有显示这个“计算”操作是如何发生的,所以不可能以特定的方式来回答。 –
2014-10-28 20:15:18