INotifyPropertyChanged不起作用

时间:2015-04-14 13:37:26

标签: c# xaml geolocation windows-phone-8.1

可能不是最好的解决方案,但我注意到我的应用程序的许多不同页面和用户控件使用相同的数据(主要是通过绑定),所以我做了以下类

public class GPSHelper : INotifyPropertyChanged
    {
        private double _speed;
        public double Speed
        {
            get
            {
                return _speed;
            }
            set
            {
                _speed = value;
                NotifyPropertyChanged("Speed");
            }
        }
        public double AvgSpeed { get; set; }
        public double MaxSpeed { get; set; }
        public double Distance { get; set; }
        public double Altitude { get; set; }
        public double Longtitude { get; set; }
        public double Latitude {get; set;}
        private int _locationChangedCounter;
        private Geolocator _locator; 
        public GPSHelper()
        {
            _locator = new Geolocator();
            _locator.MovementThreshold = 0.5;
            _locator.PositionChanged += locator_PositionChanged;
            MaxSpeed = 0;
            AvgSpeed = 0;
            Speed = 30; 
        }

        private async void locator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
        {

            Geoposition position = await _locator.GetGeopositionAsync();
            Geopoint point = args.Position.Coordinate.Point;
            //Speed = position.Coordinate.Speed.Value;
            Speed = 120; 
            Altitude = point.Position.Altitude;
            if(Speed > MaxSpeed)
            {
                MaxSpeed = Speed; 
            }
            AvgSpeed += Speed / _locationChangedCounter;
            _locationChangedCounter++;
        }

        private void NotifyPropertyChanged(string propertyname)
        {
            if(PropertyChanged!=null)
            {
                 PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;
    }

在App.xaml中我添加了这个类作为资源,我不知道我是否可以这样做,但它似乎仍然是个好主意。

<Application
    x:Class="SpeedometerGPS.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SpeedometerGPS"
    xmlns:helpers ="using:SpeedometerGPS.Helpers">
    <Application.Resources>
        <helpers:GPSHelper x:Key="GPSHelper" /> 
    </Application.Resources>
</Application>

我现在唯一的问题是PropertyChanged无法工作,它给出了一个非常有效的理由 - ,应用程序调用了一个为不同线程编组的接口。“任何建议如何解决它?

3 个答案:

答案 0 :(得分:2)

问题是进入的事件不在GUI线程上,而是在工作线程上。 然后你正在操纵速度,我认为这是一些绑定的一部分。 如果它是某些绑定的一部分,更新速度将在这些绑定中起作用,但这仅在GUI中发生更改时才有效。

最重要的是,你必须将速度或整个事件的变化分配给GUI线程。

此处说明调度到GUI线程: The application called an interface that was marshalled for a different thread in window 8

Deployment.Current.Dispatcher.BeginInvoke(() =>
{
    Speed = 120; 
});

答案 1 :(得分:2)

Geolocator文档说:

&#34;重要在访问用户位置之前调用RequestAccessAsync。那时,您的应用必须位于前台,并且必须从UI线程调用RequestAccessAsync。在用户向您的位置授予您的应用权限之前,您的应用无法访问位置数据。&#34;

https://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.geolocation.geolocator

因此,您应该将Geolocator作为其他地方的静态属性(例如App.xaml.cs用于示例),并在获取任何事件之前从UI线程中的方法调用RequestAccessAsync。

答案 2 :(得分:0)

我解决了我自己的问题,将Geolocator作为App.xaml.cs中的静态成员并在OnLaunch()中实际使用它然后分配事件处理程序解决了一段时间的问题,但整个程序崩溃了一分钟左右。谷歌搜索了几个小时之后,事实证明,为了在课堂上使用调度员,我希望你必须做这样的事情。无论您是否正在阅读,都要感谢您的努力。

await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority,() => {})