2012-11-05 30 views
1

我遇到了一個非常奇怪的問題。DevExpress GridControl無法正確更新,即使我正確設置了NotifyPropertyChanged事件

基本思路是我有一個類來保存從交易api收到的關於外匯價格的數據。每個屬性都使用如下所示的NotifyPropertyChanged方法進行設置。

class RealTimeBar 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private const double EPSILON = 0.0000001; 

    private int _id; 
    private string _symbol; 
    private int _time; 
    private float _open; 
    private float _high; 
    private float _low; 
    private float _close; 
    int _volume; 

    public RealTimeBar(int id, string symbol) 
    { 
     _id = id; 
     _symbol = symbol; 
    } 

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

    public int Id 
    { 
     get 
     { 
      return _id; 
     } 
     set 
     { 
      _id = value; 
     } 
    } 

    public string Symbol 
    { 
     get 
     { 
      return _symbol; 
     } 
     set 
     { 
      if (value != _symbol) 
      { 
       _symbol = value; 
       NotifyPropertyChanged("Symbol"); 
      } 
     } 
    } 

    public int Time 
    { 
     get 
     { 
      return _time; 
     } 
     set 
     { 
      if (value != _time) 
      { 
       _time = value; 
       NotifyPropertyChanged("Time"); 
      } 
     } 
    } 

    public float Open 
    { 
     get 
     { 
      return _open; 
     } 
     set 
     { 
      if (value != _open) 
      { 
       _open = value; 
       NotifyPropertyChanged("Open"); 
      } 
     } 
    } 

    public float High 
    { 
     get 
     { 
      return _high; 
     } 
     set 
     { 
      if (value != _high) 
      { 
       _high = value; 
       NotifyPropertyChanged("High"); 
      } 
     } 
    } 

    public float Low 
    { 
     get 
     { 
      return _low; 
     } 
     set 
     { 
      if (value != _low) 
      { 
       _low = value; 
       NotifyPropertyChanged("Low"); 
      } 
     } 
    } 

    public float Close 
    { 
     get 
     { 
      return _close; 
     } 
     set 
     { 
      if (value != _close) 
      { 
       _close = value; 
       NotifyPropertyChanged("Close"); 
      } 
     } 
    } 

    public int Volume 
    { 
     get 
     { 
      return _volume; 
     } 
     set 
     { 
      if (value != _volume) 
      { 
       _volume = value; 
       NotifyPropertyChanged("Volume"); 
      } 
     } 
    } 


} 

這是引用一個長類,但結構簡單,你可以看到。現在我連接到api,向我發送事件,並通過將api的值設置爲我定義的類來處理它。

BindingList<RealTimeBar> _realTimeBarList = new BindingList<RealTimeBar>(); 
    public Hashtable _iForexHashtable = new Hashtable(); 

    private void _UpdateForexQuote(int tickerId, int time, double open, double high, double   low, double close, int volume, 
          double wap, int count) 
    { 
     ///MessageBox.Show(tickerId.ToString()); 
     ((RealTimeBar)_iForexHashtable[tickerId]).Open = (float)open; 
     ((RealTimeBar)_iForexHashtable[tickerId]).High = (float)high; 
     ((RealTimeBar)_iForexHashtable[tickerId]).Low = (float)low; 
     ((RealTimeBar)_iForexHashtable[tickerId]).Close = (float)close; 
     ((RealTimeBar)_iForexHashtable[tickerId]).Volume = volume; 

    } 

經過一番設置後,方法_UpdateForexQuote會將即將到來的信息分發到RealTimeBar類的屬性中。一切安好。

當我啓動程序時,它不會更新。我認爲沒有數據進入。但是當我隨機點擊gridcontrol的A1cell中的某個位置時,然後點擊另一個B1cell,之前的A1cell會更新。然後,如果我點擊C1cell,那麼B1cell會更新。如果你不點擊一個單元格,它將永遠不會更新。我給你的圖片:

enter image description here

正如你所看到的,點擊前三行後,前三行顯示延遲的數據,因爲我從來沒有接觸第四行,它顯示爲零。條件是我只點擊了第五行低單元格,這就是爲什麼低不更新,但其他單元格更新。這很奇怪。我之前在使用vs 2010的devexpress 11之前使用了相同的代碼。但是現在使用devexpress 12和vs 2012,我遇到了以前從未發生過的這個問題。

UPDATE:

下面是我使用爲1的方法限定的BindingList和哈希表,2.將對象放入散列表的第一和從散列表添加所述對象到的BindingList 3.綁定的BindingList到gridcontrol 。

private void earningButtonItem_ItemClick(object sender, ItemClickEventArgs e) 
    { 
     _iTimer.AutoReset = false; 
     _iTimer.Enabled = false; 
     switchStockPool = "Earning Stock"; 
     disconnectButtonItem.PerformClick(); 
     connectButtonItem.PerformClick(); 
     _iheitanshaoEarningDBConnect = new DBConnect("heitanshaoearning"); 
     List<string>[] tempList; 
     int tempHash; 
     tempList = _iheitanshaoEarningDBConnect.SelectSymbolHighLow(); 
     _quoteEarningOnGridList.Clear(); 

     ///tempList[0].Count 
     for (int i = 0; i < tempList[0].Count; i++) 
     { 
      tempHash = Convert.ToInt32(tempList[0][i].ToString().GetHashCode()); 
      _iStockEarningHistHashtable[tempHash] = new QuoteOnGridHist(tempList[0][i], (float)Convert.ToSingle(tempList[1][i]), (float)Convert.ToSingle(tempList[2][i]), (float)Convert.ToSingle(tempList[3][i])); 
      _iStockEarningHashtable[tempHash] = new QuoteOnGrid(tempList[0][i], 0, 0); 
      _quoteEarningOnGridList.Add((QuoteOnGrid)_iStockEarningHashtable[tempHash]); 
      reqMktDataExStock(tempHash, tempList[0][i].ToString()); 
     } 

     List<string>[] tempVolumeList; 
     tempVolumeList = _iheitanshaoEarningDBConnect.SelectAverageVolume(); 
     for (int i = 0; i < tempList[0].Count; i++) 
     { 
      tempHash = Convert.ToInt32(tempVolumeList[0][i].ToString().GetHashCode()); 
      ((QuoteOnGrid)_iStockEarningHashtable[tempHash]).Average_Volume = ((float)Convert.ToSingle(tempVolumeList[1][i]))/volumeDenominator; 
     } 

     gridControl.DataSource = _quoteEarningOnGridList; 
    } 
    ///////////////////// 

現在,當價格更新事件來臨時,下面的方法將更新散列表中的對象屬性。由於我在對象中定義了Notifypropertychanged,它應該更新bingdinglist和gridcontrol中的對象。

private void _UpdateStockMarketQuote(int tikcerId, int field, double price, int canAutoExecute) 
    { 
     ////MessageBox.Show(tikcerId.ToString() + field.ToString() + price.ToString()); 
     if (switchStockPool == "Selected Stock") 
     { 
      if (field == 4) 
      { 
       ((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_High = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).High)/((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close; 
       ((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_Low = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Low)/((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close; 
       ((QuoteOnGrid)_iStockHashtable[tikcerId]).Last_Price = (float)price; 
      } 
      //else if (field == 1) 
      //{ 
      // ((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_High = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).High)/((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close; 
      // ((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_Low = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Low)/((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close; 
      //} 
     } 
     else if (switchStockPool == "Earning Stock") 
     { 
      if (field == 4) 
      { 
       ((QuoteOnGrid)_iStockEarningHashtable[tikcerId]).Gap_From_High = ((float)price - ((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).High)/((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).Close; 
       ((QuoteOnGrid)_iStockEarningHashtable[tikcerId]).Gap_From_Low = ((float)price - ((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).Low)/((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).Close; 
       ((QuoteOnGrid)_iStockEarningHashtable[tikcerId]).Last_Price = (float)price; 

      } 
      //else if (field == 1) 
      //{ 
      // ((quoteongrid)_istockearninghashtable[tikcerid]).gap_from_high = ((float)price - ((quoteongridhist)_istockearninghisthashtable[tikcerid]).high)/((quoteongridhist)_istockearninghisthashtable[tikcerid]).close; 
      // ((quoteongrid)_istockearninghashtable[tikcerid]).gap_from_low = ((float)price - ((quoteongridhist)_istockearninghisthashtable[tikcerid]).low)/((quoteongridhist)_istockearninghisthashtable[tikcerid]).close; 
      //} 
     } 

    } 
+0

您是否正從另一個線程更新? –

+0

@AseemGautam是的。我想是這樣。我怎麼修復它?現在它正在工作。我讓它運行了幾個小時,它更新了正確的數據。但我認爲這仍然是延遲。我不太瞭解線程。 –

回答

0

你不僅需要有PropertyChanged事件中的一類,你需要實現INotifyPropertyChanged。這就是網格知道一個班級可以通知變化的方式。