Как переместить GPS-наблюдатель в суперкласс App.xaml и отправлять события на другие страницы / классы? - PullRequest
3 голосов
/ 06 апреля 2011

Я новичок в разработке для silverlight / WPF и WP7, однако я знаком с разработкой C # с использованием консоли или формы Windows, так что терпите меня!

Я пытаюсь создать приложение, учитывающее местоположение, используя Silverlight SDK и классы Microsoft.Maps.MapControl и System.Device.Location. У меня проблема с доступом к «наблюдателю» с других страниц. Каков наилучший способ сделать это. Я хочу поместить его за пределы моих классов страниц GUI, чтобы при переключении между страницами вы не проверяли новое местоположение в потоке пользовательского интерфейса и не выполняли дублирующую работу.

Вот краткое описание того, как я думаю, что это должно быть сделано (перевод GPS-наблюдателя в суперкласс приложения -> Диспетчер на классы страниц при изменении события), кто-нибудь, пожалуйста, поправьте меня! Основная проблема в том, что я не могу получить доступ к классам страницы (MainPage.xaml и ListView.xaml) без создания экземпляров или статических методов. Если я создаю статический метод на страницах, он бесполезен, потому что я все равно не могу взаимодействовать со страницей (например, установить строку состояния, когда местоположение изменилось, или переместить вид карты на новое место). Каков наилучший способ сделать это? Я думал просто установить новый статический объект местоположения в классе App и получить доступ к нему из подклассов, но это ручная операция. Кажется, что диспетчер - это способ сделать это, но есть ли способ ссылаться на страницу без конкретизация

В приложениях Windows Forms, которые я использую - readonly FormClass form = (FormClass)Application.OpenForms["formname"];

Вот пример моего кода ...

App.xaml.cs (класс приложения) - По-видимому, это суперкласс для всего приложения WP7, поэтому я разместил свой наблюдатель здесь.

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
}

Обновлено - вот так у меня получилось так, как мне нужно ...

Создал публичный класс Loc для моего местоположения-

 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 как статический объект, чтобы я мог использовать эту информацию во время работы приложения.

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();

Затем внутри моего приложения, когда мне нужно получить доступ к информации о местоположении, я могу просто использовать-

App.AppLoc.CurLoc или App.AppLoc.LocStatus

Ответы [ 2 ]

0 голосов
/ 06 апреля 2011

Используйте методы PhoneApplicationPage OnNavigatedTo () и OnNavigatedFrom () для регистрации / отмены регистрации получения позиции.Объект Watcher может быть определен в классе Application по вашему плану.Отдельные страницы могут использовать статическое свойство Application.Current для доступа к объекту Application.

Я думаю, что у вас есть все, что вам нужно.

Кстати, вам не нужно отправлять события, поскольку GeoCoordinateWatcher доставляет события в пользовательском интерфейсе.контекст темы.

Примечание: мы (Resco) только что опубликовали обновление нашей библиотеки Location.Может быть, эта статья может дать вам некоторое представление о том, что можно сделать с помощью GPS и служб на основе определения местоположения.

0 голосов
/ 06 апреля 2011

Вы можете использовать систему обмена сообщениями, когда изменяется положение или статус. Все соответствующие страницы могут подписаться на такие сообщения.

В качестве альтернативы, в зависимости от структуры вашего приложения, вы можете обрабатывать события централизованно и применять к общей модели представления, на которую ссылаются другие страницы.

...