2011-05-13 21 views
3

DataGridViewで非常に奇妙な問題が発生しています。私は私のカスタムコントロールに3つのグリッドを持っています。私はこの実装を使用しています:私はデザイナを使用してバインディングソースとdatagridviewをリンクしています。私のコントロール呼び出しのユーザは、いくつかのパラメータでメソッドを初期化します。コントロールは3つの内部リスト(実際には2つのリストとオブジェクトの辞書)を設定します。リストが作成された後、私はリストをバインディングソースに割り当てます。dataGridViewとBindingSourceを使用すると奇妙な問題が発生する

2つのグリッドは正常に動作していますが、そのうちの1つは表示されません(下位のリストにはデータが含まれています)。私は、この行を変更した場合:

bindingSource.DataSource = myList; 
datagridView.DataSource = null; 
datagridView.DataSource = bindingSource; 

bindingSource.DataSource = myList; 

をグリッドは、しかし、グリッド上の任意のイベントが例外(IndexOutOfRangeException「インデックスが発生します、行が表示されます-1の値を持っていません。 "このコード行で)。あなたの助けのための

public partial class DisplayTradeSplitValuesControl : UserControl 
    { 
     List<TradeSplittingRatio> templateDatasource_ = new List<TradeSplittingRatio>(); 
     List<TradeSplittingRatio> fundsDatasource_ = new List<TradeSplittingRatio>(); 
     Dictionary<string,List<TradeSplittingRatio>> portfolioDatasource_ = 
      new Dictionary<string,List<TradeSplittingRatio>>(); 

     private string instrumentName_ = string.Empty; 

     private RoundingRuleAbstract roundingRule_; 

     public DisplayTradeSplitValuesControl() 
     { 
      InitializeComponent(); 
     } 

     public void Initialize(string portfolioName, string instrumentName, double value) 
     { 
      ConfigManager.GetConfigManager().LoadPortfolioCache(); 
      ConfigManager.GetConfigManager().LoadPortfolioRatioCache();    
      instrumentName_ = instrumentName; 
      roundingRule_ = GetGranularity(instrumentName_); 
      PopulateTemplateDatasource(portfolioName, value); 
      PopulateFundDatasource(portfolioName, value); 
      PopulatePortfolioAndManagedAccountDatasource(); 
      PopulateGrid(); 
     } 

     private void PopulateGrid() 
     { 
      templateSplittingRatioBindingSource.DataSource = templateDatasource_; 
      fundTradeSplittingRatioBindingSource.DataSource = fundsDatasource_; 
      templateDataGridView.Refresh(); 
      //fundsDataGridView.DataSource = null; //not working hack!!! 
      //fundsDataGridView.DataSource = fundTradeSplittingRatioBindingSource.DataSource; 
      fundsDataGridView.Refresh(); 
      if (fundsDatasource_.Count > 0) 
      { 
       string portfolioName = fundsDatasource_[0].ToPortfolio; 
       portfolioTradeSplittingRatioBindingSource.DataSource = portfolioDatasource_[portfolioName]; 

       portfolioDataGridView.Refresh(); 
      } 

     } 

     private void PopulateTemplateDatasource(string portfolioName, double value) 
     { 
      templateDatasource_.Clear(); 
      TradeSplittingRatio template = new TradeSplittingRatio(string.Empty, portfolioName, 0, value, 0); 
      templateDatasource_.Add(template); 
     } 

     private void PopulateFundDatasource(string portfolioName, double value) 
     { 
      fundsDatasource_.Clear(); 
      if (ConfigManager.GetConfigManager().ActivePortfolioCache.ContainsKey(portfolioName) == true) 
      { 
       Portfolio portfolio = ConfigManager.GetConfigManager().ActivePortfolioCache[portfolioName]; 
       if (ConfigManager.GetConfigManager().ActivePortfolioRatioCache.ContainsKey(portfolio) == true) 
       { 
        List<KeyValuePair<Portfolio, double>> portfolioRatio = 
         ConfigManager.GetConfigManager().ActivePortfolioRatioCache[portfolio]; 

        foreach (KeyValuePair<Portfolio, double> ratio in portfolioRatio) 
        { 
         fundsDatasource_.Add(new TradeSplittingRatio(portfolioName, 
                   ratio.Key.Identifier, 
                   ratio.Value, 
                   roundingRule_.Calculate(new Ratio(ratio.Value).Calculate(value)), 
                   roundingRule_.Granularity)); 
        } 
       } 
      } 
     } 

     private void PopulatePortfolioAndManagedAccountDatasource() 
     { 
      portfolioDatasource_.Clear(); 

      List<TradeSplittingRatio> cloneFundsDatasource = new List<TradeSplittingRatio>(); 
      foreach (TradeSplittingRatio fund in fundsDatasource_) 
      { 
       cloneFundsDatasource.Add((TradeSplittingRatio)fund.Clone()); 
      } 

      foreach (TradeSplittingRatio fund in cloneFundsDatasource) 
      { 
       if (portfolioDatasource_.ContainsKey(fund.ToPortfolio) == false) 
        portfolioDatasource_.Add(fund.ToPortfolio,new List<TradeSplittingRatio>()); 

       Portfolio portfolio = ConfigManager.GetConfigManager().ActivePortfolioCache[fund.ToPortfolio]; 
       List<KeyValuePair<Portfolio, double>> portfolioRatio = 
        ConfigManager.GetConfigManager().ActivePortfolioRatioCache[portfolio]; 

       foreach (KeyValuePair<Portfolio, double> ratio in portfolioRatio) 
       { 
        portfolioDatasource_[fund.ToPortfolio].Add(new TradeSplittingRatio 
         (fund.ToPortfolio, 
         ratio.Key.Identifier, 
         ratio.Value, 
         roundingRule_.Calculate(new Ratio(ratio.Value).Calculate(fund.Amount)), 
         roundingRule_.Granularity)); 
       } 
      } 
     } 

     private RoundingRuleAbstract GetGranularity(string instrumentName) 
     { 
      ConfigManager.GetConfigManager().LoadBondCache(); 
      ConfigManager.GetConfigManager().LoadInstrumentCache(); 

      if (ConfigManager.GetConfigManager().ActiveInstrumentCache.ContainsKey(instrumentName)) 
      { 
       if (string.Equals(ConfigManager.GetConfigManager().ActiveInstrumentCache[instrumentName].InstrumentType.Identifier,"CASH") || 
        string.Equals(ConfigManager.GetConfigManager().ActiveInstrumentCache[instrumentName].InstrumentType.Identifier, "FX")) 
       { 
        return new RoundingRule.RoundHalfUpRule(ConfigManager.GetConfigManager().ActiveInstrumentCache[instrumentName].Currency.Granularity); 
       } 
       if (ConfigManager.GetConfigManager().ActiveBondCache.ToList(). 
         Where(c => c.Value.InstrumentId == ConfigManager.GetConfigManager().ActiveInstrumentCache[instrumentName].InstrumentId).Count() > 0) 
       { 
        return new RoundingRule.RoundHalfUpRule(
         ConfigManager.GetConfigManager().ActiveBondCache.ToList(). 
         Where(c => c.Value.InstrumentId == ConfigManager.GetConfigManager().ActiveInstrumentCache[instrumentName].InstrumentId).First().Value.Granularity); 
       } 
      } 
      return new RoundingRule.RoundHalfUpRule(1.0); 
     } 

     private void fundsDataGridView_SelectionChanged(object sender, EventArgs e) 
     { 
      if (fundsDataGridView.Focused) 
      { 
       TradeSplittingRatio fund = (TradeSplittingRatio)fundsDataGridView.SelectedRows[0].DataBoundItem; 
       portfolioTradeSplittingRatioBindingSource.DataSource = portfolioDatasource_[fund.ToPortfolio]; 
       portfolioDataGridView.Refresh();     
      } 
      //Validate(); 
     } 
    //other stuff not important 
    } 
} 

ありがとう:

これは、関連するコードです。

答えて

1

私はすべてのコードを介して取得していない、私は最後までスキップして、この部分は私に飛び出し:

 private void fundsDataGridView_SelectionChanged(object sender, EventArgs e) 
     { 
      if (fundsDataGridView.Focused) 
      { 
       TradeSplittingRatio fund = (TradeSplittingRatio)fundsDataGridView.SelectedRows[0].DataBoundItem; 
       portfolioTradeSplittingRatioBindingSource.DataSource = portfolioDatasource_[fund.ToPortfolio]; 
       portfolioDataGridView.Refresh();     
      } 
      //Validate(); 
     } 

あなたはDataGridView.SelectedRows[0]にアクセスするあなたはそれが任意の項目が含まれているかどうかを確認するためにチェックしていないにもかかわらず、 。選択範囲が空になると(通常、データソースが変更またはクリアされたため)、SelectionChangedが起動する可能性があります。

ここで境界線をテストしないと、他の場所で境界線をテストできない可能性があります。あなたが持っているエラーメッセージは正確に言っています:何か、多分イベントがインデックス-1で生成され、行#-1にアクセスしようとしていますが、これはもちろん存在しません。

更新私が引用されたコードを使用して、他の潜在的な問題は、集束チェックです。なぜここで焦点を当てているのかわからないのですが、DGVは現在、ユーザーが編集しているセル内の(単一の)子コントロールを使用しています。その "編集コントロール"にフォーカスがある場合、DGV.Focusedはfalseになります。

+0

ありがとうございます、あなたは良い点があります(私はガードを入れます)。しかし、それは私の問題の原因ではありません。私はメソッドの中にブレークポイントを入れ、ブレークポイントはヒットしません。 –

+0

@アレアンドロ:私が指摘していたことは、あなたの問題に接していたことが明らかになったと思いました。私は "何か、おそらくイベント..."と述べています。つまり、問題は私が指していた場所ではありません。私は、あなたが仮定を確認できないコードを持っていることを指摘しました。他の場所では、前提を確認できないコードがいくつかあります。 – Tergiver

関連する問題