如何在 xaml (MVVM + WP8) 中显示调度程序数据

本文关键字:显示 调度程序 数据 WP8 xaml MVVM | 更新日期: 2023-09-27 18:35:07

我想在手机屏幕上查看我当前的位置。我在这个项目中使用 MVVM 模型。

XAML

 <TextBlock Name="XBlock" 
                               Visibility="Visible"
                               Text="{Binding Path=XValue, Mode=OneWay}" 
                               Margin="0,0,359,0" Height="75"/>

视图模型

public string XValue {get ; set ; }
        public string YValue { get; set; }
        public string ZValue { get; set; }
        void _accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e) 
        {
            var position = e.SensorReading.Acceleration;
            SmartDispatcher.Dispatch(() =>
            {
                this.XValue = position.X.ToString("0.0000");
                this.YValue = position.Y.ToString("0.0000");
                this.ZValue = position.Z.ToString("0.0000");
            });
        }

调度程序类

public static Dispatcher DispatchObject { get; set; }
        public static void Dispatch(Action action)
        {
            if (DispatchObject == null || DispatchObject.CheckAccess())
            {
                action();
            }
            else
            {
                DispatchObject.InvokeAsync(action);
            }
        }

文本块为空。来自加速度计的数据被正确读取(由Degug检查)。

当我将方法XValue更改为:

 public string XValue {
            get { return "ds"; }
            set{ XValue = "fd";} 
        }

在文本块中是:"ds"。我该怎么做才能查看当前的加速度计数据?

如何在 xaml (MVVM + WP8) 中显示调度程序数据

您必须将

INotifyPropertyChanged接口添加到ViewModel,以便Xaml知道数据何时更改并可以更新。

例:

public class MyViewModel : INotifyPropertyChanged
{
    private string _zValue;
    private string _yValue;
    private string _xValue;
    public string XValue
    {
        get { return _xValue; }
        set { _xValue = value; NotifyPropertyChanged("XValue"); }
    }
    public string YValue
    {
        get { return _yValue; }
        set { _yValue = value; NotifyPropertyChanged("YValue"); }
    }
    public string ZValue
    {
        get { return _zValue; }
        set { _zValue = value; NotifyPropertyChanged("ZValue"); }
    }
    void _accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
    {
        var position = e.SensorReading.Acceleration;
        SmartDispatcher.Dispatch(() =>
        {
            this.XValue = position.X.ToString("0.0000");
            this.YValue = position.Y.ToString("0.0000");
            this.ZValue = position.Z.ToString("0.0000");
        });
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

不工作。Erron in:

PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

详:

System.UnauthorizedAccessException was unhandled by user code
  HResult=-2147024891
  Message=Invalid cross-thread access.
  Source=System.Windows
  StackTrace:
       at MS.Internal.XcpImports.CheckThread()
       at MS.Internal.XcpImports.GetValue(IManagedPeerBase managedPeer, DependencyProperty property)
       at System.Windows.DependencyObject.GetOldValue(DependencyProperty property, EffectiveValueEntry& oldEntry)
       at System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation)
       at System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp)
       at System.Windows.Data.BindingExpression.SendDataToTarget()
       at System.Windows.Data.BindingExpression.SourcePropertyChanged(PropertyPathListener sender, PropertyPathChangedEventArgs args)
       at System.Windows.PropertyPathListener.RaisePropertyPathStepChanged(PropertyPathStep source)
       at System.Windows.PropertyAccessPathStep.RaisePropertyPathStepChanged(PropertyListener source)
       at System.Windows.CLRPropertyListener.SourcePropertyChanged(Object sender, PropertyChangedEventArgs args)
       at System.Windows.Data.WeakPropertyChangedListener.PropertyChangedCallback(Object sender, PropertyChangedEventArgs args)
       at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)
       at ITWEMPhone.ViewModel.NotifyPropertyChanged(String propertyName)
       at ITWEMPhone.ViewModel.set_XValue(String value)
       at ITWEMPhone.ViewModel.<>c__DisplayClass1.<_accelerometer_CurrentValueChanged>b__0()
       at ITWEMPhone.SmartDispatcher.Dispatch(Action action)
       at ITWEMPhone.ViewModel._accelerometer_CurrentValueChanged(Object sender, SensorReadingEventArgs`1 e)
       at System.EventHandler`1.Invoke(Object sender, TEventArgs e)
       at Microsoft.Devices.Sensors.SensorBase`1.FireOnReadingChanged(SensorReadingEventArgs`1 sample)
       at Microsoft.Devices.Sensors.SensorBase`1.OnNewReading(Object sender, NativeSensorEventArgs sample)
       at Microsoft.Devices.Sensors.SensorBase`1.<>c__DisplayClass7.<.ctor>b__3(Object sender, NativeSensorEventArgs args)
       at Microsoft.Devices.Sensors.SensorCallback.OnNewReading(IntPtr pNewReading)
  InnerException: 

所以我将方法更改为:

 private void NotifyPropertyChanged(string propertyName)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() => PropertyChanged(this, new PropertyChangedEventArgs(propertyName)));
        }

和 XAML 以:

<TextBlock Text="{Binding XValue, Mode=TwoWay}" Height="67" RenderTransformOrigin="0.5,1.134"/>

并完美:)妈妈,对某人有用!