从Winform调用带有Bing映射的WPF窗口
本文关键字:映射 WPF 窗口 Bing Winform 调用 | 更新日期: 2023-09-27 18:28:14
我正在开发一个Windows窗体,它将获取用户的纬度和经度,执行一些长计算,并在地图上显示用户的位置和一些路线。地图将显示在一个单独的WPF窗口使用必应地图API。由于用户输入纬度和经度后需要执行的计算很复杂,需要花费大量时间,因此我需要在后台线程中执行这些计算,并从该后台线程调用新的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窗口称为MainWindow。这是它的代码:
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地图不会显示世界地图。相反,背景是灰色的,如果我尝试缩放或更改窗口的大小,就会抛出System.NullReferenceException
(未设置为对象实例的对象引用)。调试器告诉我在System.Windows.Threading.Dispatcher.Run();
行抛出了异常。然而,如果我不尝试将地图居中,也不将地图设置为"空中"模式,一切都会正常工作。我应该怎么做才能从后台线程调用WPF窗口并在运行时更改Bing Map的属性而不会出现任何问题?我已经检查过,如果从主UI线程调用WPF窗口,一切都会正常工作。有趣的是,如果我关闭WPF窗口并再次按下按钮,新的WPF窗口会正常显示Bing地图,并且System.NullReferenceException
不会被抛出。
我最终在一个UI元素上调用了BeginInvoke()。它允许我创建一个创建UI元素的线程,以执行我作为参数传递的函数。