如何将GPS watcher移至App.xaml超类并将Dispatch事件移至其他页面/类? [英] How do I move GPS watcher to App.xaml superclass and Dispatch events to other pages/classes?

查看:133
本文介绍了如何将GPS watcher移至App.xaml超类并将Dispatch事件移至其他页面/类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是开发Silverlight/WPF和WP7的新手,但是我熟悉使用控制台或Windows窗体开发C#的经验,所以请多多包涵!

I am new to developing for silverlight/WPF and WP7, however I am familiar with developing C# using console or windows form, so bear with me!

我正在尝试使用Silverlight SDK和Microsoft.Maps.MapControl和System.Device.Location类创建一个位置感知应用程序.我遇到的问题是从其他页面访问观察者".做这个的最好方式是什么.我想将其放在我的GUI页面类之外,以便在页面之间切换时,您无需检查UI线程上的新位置并进行重复的工作.

I am trying to create a location aware app using the Silverlight SDK and the Microsoft.Maps.MapControl and the System.Device.Location classes. The problem I am having is accessing the "watcher" from other pages. What is the best way to do this. I want to put it outside of my GUI page classes so that when switching between pages, you are not checking for a new location on the UI thread and doing duplicate work..

以下是我认为应如何做的概述(将GPS watcher移至应用程序超类->调度程序以更改事件更改为页面类),请有人纠正我!这样做的主要问题是,如果没有实例化或静态方法,我将无法访问Page类(MainPage.xaml和ListView.xaml).如果在页面上创建静态方法,则该方法无用,因为无论如何我都无法与页面进行交互(例如,设置状态栏以更改位置或将mapview移至新位置).做这个的最好方式是什么?我以为只是在App类中设置了一个新的静态位置对象,并可以从子类中访问它,但这是手动操作.实例化?

Here is an outline of how I think it should be done (moving GPS watcher to App superclass -> Dispatcher to page classes on event change), somebody please correct me! The main problem with this is I cannot access the Page classes (MainPage.xaml and ListView.xaml) without instantiation or static methods. If I make a static method on the pages, it is useless because I cannot interact with the page anyway (such as setting a status bar that location changed or move the mapview to the new location). What is the best way to do this? I have thought just setting a new static location object in the App class and access that from the sub classes but this is manual operation.. It seems that the dispatcher is the way to do it, but is there a way to reference a page without instantiation?

在我使用的Windows Forms应用程序中-readonly FormClass form = (FormClass)Application.OpenForms["formname"];

In Windows Forms apps I use - readonly FormClass form = (FormClass)Application.OpenForms["formname"];

这是我的代码的示例...

Here is an example of my code...

App.xaml.cs(应用程序类)-显然,这是整个WP7应用程序的超类,因此我将观察者放在这里.

App.xaml.cs (App class)- Apparently this is the super class for the entire WP7 app so I put my watcher here.

Public Partial Class App : Application
{
Private IGeoPositionWatcher<GeoCoordinate> _watcher;
    Public App()
   {
     //App constructor
      //Mock GPS services on WP7 emulator
            if (_watcher == null)
            {
                var events = new[] {
                    new  GeoCoordinateEventMock { Latitude=33.43, Longitude=-112.02, Time=new TimeSpan(0,0,1) },
                   };
                _watcher = new EventListGeoLocationMock(events);
            }
            //add event handlers for statuschanged and positionchanged
            _watcher.StatusChanged += WatcherStatusChanged;
            _watcher.PositionChanged += WatcherPositionChanged;
            //start watcher
            _watcher.Start();
    }
#event handlers
       public void WatcherStatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() => MainPage.MyStatusChanged(e));
          Deployment.Current.Dispatcher.BeginInvoke(() => OtherPage.MyStatusChanged(e));
        }
        public void WatcherPositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() => MainPage.MyPositionChanged(e));
           Deployment.Current.Dispatcher.BeginInvoke(() => OtherPage.MyPositionChanged(e));
        }

}

MainPage.xaml.cs (MainPage class)-
public void MyPositionChanged(GeoPositionChangedEventArgs<GeoCoordinate> e)
{
//do some stuff
}
public void MyStatusChanged(GeoPositionStatusChangedEventArgs e)
{
//do some stuff
}

已更新-这就是我按照需要的方式进行工作的方式-

Updated- This is how I got it working the way I needed-

为我的位置创建了一个公共类Loc-

Created a public class Loc for my location-

 public class Loc
{

    private readonly GeoCoordinateWatcher _watcher;
    public Location CurLoc { get; set; }
    public string LocStatus { get; set; }

   public Loc()
    {
        if (_watcher != null) return;
        //---get the default accuracy-

        _watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default)


                      {
                          MovementThreshold = 1000
                      };


        //add event handlers for statuschanged and positionchanged
        _watcher.StatusChanged += WatcherStatusChanged;
        _watcher.PositionChanged += WatcherPositionChanged;

        //start watcher
        _watcher.Start();
    }

   private void MyPositionChanged(GeoPositionChangedEventArgs<GeoCoordinate> e)
    {
        //called from the _watcher Position changed eventHandler

            CurLoc = new Location(e.Position.Location.Latitude, e.Position.Location.Longitude);



    }

    private void MyStatusChanged(GeoPositionStatusChangedEventArgs e)
    {
        //called from the _watcher position status changed event handler

        switch (e.Status)
        {
            case GeoPositionStatus.Disabled:
                LocStatus = "Location services disabled!";

                break;
            case GeoPositionStatus.Initializing:
                LocStatus = "Finding current location...";

                break;
            case GeoPositionStatus.NoData:
                LocStatus = "No location data available...";

                break;
            case GeoPositionStatus.Ready:
                LocStatus = "Found you";

                break;
        }
    }

    private  void WatcherStatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
    {
        Deployment.Current.Dispatcher.BeginInvoke(() => MyStatusChanged(e));
    }

    private void WatcherPositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
    {
        Deployment.Current.Dispatcher.BeginInvoke(() => MyPositionChanged(e));

    }
}

然后,我将我的App.xaml.cs类中的此类实例化为静态对象,以便在应用操作期间利用这些信息.

Then I instantiate this class in my App.xaml.cs class as a static object so I can utilize the information during the app operation.

public partial class App 
{
    /// <summary>
    /// Provides easy access to the root frame of the Phone Application.
    /// </summary>
    /// <returns>The root frame of the Phone Application.</returns>
    public PhoneApplicationFrame RootFrame { get; private set; }

           public static Loc AppLoc = new Loc();

然后,只要需要访问位置信息就可以在我的应用程序内部使用

Then inside my app whenever I need to access location information I can just use-

App.AppLoc.CurLoc或App.AppLoc.LocStatus

App.AppLoc.CurLoc or App.AppLoc.LocStatus

推荐答案

使用PhoneApplicationPage方法OnNavigatedTo()和OnNavigatedFrom()来注册/取消注册位置接收. 您可以在计划时在Application类中定义Watcher对象. 各个页面可以使用静态属性Application.Current来访问Application对象.

Use PhoneApplicationPage methods OnNavigatedTo() and OnNavigatedFrom() to register/unregister position receiving. Watcher object may be defined in the Application class as you plan. Individual pages can use static property Application.Current to access Application object.

我认为您拥有所需的一切.

I think you have all you need.

顺便说一句,您不需要分配事件,因为GeoCoordinateWatcher在UI线程上下文中传递事件.

BTW, you should not need event dispatching as the GeoCoordinateWatcher delivers events in the UI thread context.

旁注: 我们(Resco)刚刚发布了位置库的更新.也许本文可以使您有所了解通过GPS和基于位置的服务完成.

A side remark: We (Resco) just published an update to our Location library. Maybe this article could give you some idea what can be done with GPS and location-based services.

这篇关于如何将GPS watcher移至App.xaml超类并将Dispatch事件移至其他页面/类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆