如何在xaml中显示Dispatcher数据(MVVM + WP8)

时间:2013-10-13 21:07:32

标签: c# xaml data-binding mvvm windows-phone-8

我希望在手机屏幕上看到我当前的位置。我在这个项目中使用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");
            });
        }

Dispatcher class

public static Dispatcher DispatchObject { get; set; }

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

TextBlock为空。正确读取加速度计的数据(由Degug检查)。

当我将方法XValue更改为:

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

在TextBlock中是:“ds”。 如何查看当前的加速度计数据?

2 个答案:

答案 0 :(得分:0)

您必须将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));
        }
    }
}

答案 1 :(得分:-1)

不行。错误:

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"/>

工作完美:)妈妈对某人有用!