2010-11-05 63 views
2

我試圖使用抖動來清除inkpresenter的內容,但是抖動只會導致我的應用程序崩潰。下面是代碼:WP7中的加速度計故障

public class ShakeDetect 
{ 
    private Accelerometer _accelerometer = null; 
    object SyncRoot = new object(); 
    private int _minimumShakes; 
    ShakeRecord[] _shakeRecordList; 
    private int _shakeRecordIndex = 0; 
    private const double MinimumAccelerationMagnitude = 1.2; 
    private const double MinimumAccelerationMagnitudeSquared = MinimumAccelerationMagnitude * MinimumAccelerationMagnitude; 
    private static readonly TimeSpan MinimumShakeTime = TimeSpan.FromMilliseconds(500); 

    public event EventHandler<EventArgs> ShakeEvent = null; 


    protected void OnShakeEvent() 
    { 
     if (ShakeEvent != null) 
     { 
      ShakeEvent(this, new EventArgs()); 
     } 
    } 



    [Flags] 
    public enum Direction 
    { 
     None = 0, 
     North = 1, 
     South = 2, 
     East = 8, 
     West = 4, 
     NorthWest = North | West, 
     SouthWest = South | West, 
     SouthEast = South | East, 
     NorthEast = North | East 
    } ; 

    public struct ShakeRecord 
    { 
     public Direction ShakeDirection; 
     public DateTime EventTime; 
    } 


    public ShakeDetect() 
     : this(2) 
    { 

    } 
    public ShakeDetect(int minShakes) 
    { 
     _minimumShakes = minShakes; 
     _shakeRecordList = new ShakeRecord[minShakes]; 
    } 

    public void Start() 
    { 
     lock (SyncRoot) 
     { 
      if (_accelerometer == null) 
      { 
       _accelerometer = new Accelerometer(); 
       _accelerometer.ReadingChanged += new EventHandler<AccelerometerReadingEventArgs>(_accelerometer_ReadingChanged); 
       _accelerometer.Start(); 
      } 
     } 
    } 

    public void Stop() 
    { 
     lock (SyncRoot) 
     { 
      if (_accelerometer != null) 
      { 
       _accelerometer.Stop(); 
       _accelerometer.ReadingChanged -= _accelerometer_ReadingChanged; 
       _accelerometer = null; 
      } 
     } 
    } 

    Direction DegreesToDirection(double direction) 
    { 
     if ((direction >= 337.5) || (direction <= 22.5)) 
      return Direction.North; 
     if ((direction <= 67.5)) 
      return Direction.NorthEast; 
     if (direction <= 112.5) 
      return Direction.East; 
     if (direction <= 157.5) 
      return Direction.SouthEast; 
     if (direction <= 202.5) 
      return Direction.South; 
     if (direction <= 247.5) 
      return Direction.SouthWest; 
     if (direction <= 292.5) 
      return Direction.West; 
     return Direction.NorthWest; 
    } 

    void CheckForShakes() 
    { 
     int startIndex = (_shakeRecordIndex - 1); 
     if (startIndex < 0) startIndex = _minimumShakes - 1; 
     int endIndex = _shakeRecordIndex; 

     if ((_shakeRecordList[endIndex].EventTime.Subtract(_shakeRecordList[startIndex].EventTime)) <= MinimumShakeTime) 
     { 
      OnShakeEvent(); 
     } 
    } 
    void _accelerometer_ReadingChanged(object sender, AccelerometerReadingEventArgs e) 
    { 

     if ((e.X * e.X + e.Y * e.Y) > MinimumAccelerationMagnitudeSquared) 
     { 

      double degrees = 180.0 * Math.Atan2(e.Y, e.X)/Math.PI; 
      Direction direction = DegreesToDirection(degrees); 


      if ((direction & _shakeRecordList[_shakeRecordIndex].ShakeDirection) != Direction.None) 
       return; 
      ShakeRecord record = new ShakeRecord(); 
      record.EventTime = DateTime.Now; 
      record.ShakeDirection = direction; 
      _shakeRecordIndex = (_shakeRecordIndex + 1) % _minimumShakes; 
      _shakeRecordList[_shakeRecordIndex] = record; 

      CheckForShakes(); 

     } 
    } 

} 

然後在我的應用程序使用:被檢測到的抖動最後,當

 private ShakeDetect _shakeDecetor; 

    // Constructor 
    public MainPage() 
    { 
     InitializeComponent(); 
     _shakeDecetor = new ShakeDetect(); 
     _shakeDecetor.ShakeEvent += new EventHandler<EventArgs>(_shakeDetect_ShakeEvent); 
     _shakeDecetor.Start(); 

void _shakeDetect_ShakeEvent(object sender, EventArgs e) 
    { 
     CanvasIP.Strokes.Clear(); 
     CanvasIP.Background = new SolidColorBrush(Colors.Black); 
    } 

我猜測,這個問題是某處在我的ShakeDetect類中,或在ShakeEvent中。

確定,所以從漢斯的建議我的代碼應該是:

void _shakeDetect_ShakeEvent(object sender, EventArgs e) 
    { 
     this.Dispatcher.BeginInvoke(() => 
      { 
       CanvasIP.Strokes.Clear(); 
       CanvasIP.Background = new SolidColorBrush(Colors.Black); 
      }); 
    } 

現在這是正確的嗎?

+0

您是否收到異常?如果是這樣,什麼例外?它扔在哪裏? – ctacke 2010-11-05 18:44:55

+0

不幸的是,我實際上沒有設備來測試它。我認爲一切正常,但測試失敗。真的不是一個簡單的方法來在模擬器中進行測試。 – BigPete 2010-11-06 00:35:09

回答

4

ReadingChanged事件在另一個線程上引發。你可以而不是直接觸摸UI組件,你必須編組回調主線程。使用Dispatcher.BeginInvoke(),這在MSDN library article中有很好的描述。

+0

我會檢查一下。 – BigPete 2010-11-06 00:35:45

+0

我想我知道了...你能檢查我編輯的代碼嗎? – BigPete 2010-11-06 00:57:29

+2

我搖了我的筆記本電腦,它沒有崩潰。好兆頭 :) – 2010-11-06 01:19:44