6

テキストファイルを1行ずつ読み取り、配列に挿入しています。

次に、custIndexというこのリストがあります。このリストには、特定のインデックス、つまり有効なコードであるかどうかを確認するためにテストしているitems配列のインデックスが含まれています。(たとえば、custIndex [0] = 7なので、items [7-1]の値をチェックして、ここにある2つの辞書で有効かどうかを確認します)。次に、無効なコードがある場合は、その行(items配列)をdataGridView1に追加します。

重要なのは、dataGridView1の一部の列がコンボボックス列であるため、ユーザーは正しい値を選択できるということです。items配列を追加しようとすると、例外が発生します:「DataGridViewで次の例外が発生しました:System.ArgumentException:DataGridViewComboBoxCell値が無効です。」

コンボボックスが正しいデータソースで正しく追加されたことはわかっています。items[0]のように、items配列にいくつかのアイテムを追加するだけで、コンボボックスは正常に表示され、例外はスローされません。問題は、items配列の誤った値をdataGridView1行に追加しようとしたときだと思います。

どう対処したらいいのかわからない。その値を除いて、アイテムにすべてのアイテムを追加する方法はありますか?または、アイテムから値を追加して、入力されたドロップダウンアイテムと一緒にコンボボックスのセルに表示させることはできますか?

if(choosenFile.Contains("Cust"))
{
    var lines = File.ReadAllLines(path+"\\"+ choosenFile);

    foreach (string line in lines)
    {
        errorCounter = 0;
        string[] items = line.Split('\t').ToArray();

        for (int i = 0; i <custIndex.Count; i++)
        {
            int index = custIndex[i];
            /*Get the state and country codes from the files using the correct indices*/
            Globals.Code = items[index - 1].ToUpper();

            if (!CountryList.ContainsKey(Globals.Code) && !StateList.ContainsKey(Globals.Code))
            {
                errorCounter++;

                dataGridView1.Rows.Add(items);
            }
        }//inner for

        if (errorCounter == 0)
            dataGridView2.Rows.Add(items);

    }//inner for each

}//if file is a customer file
4

1 に答える 1

6

テキストファイルに次のものが含まれているとします。

オーストラリアPNG、インドアフリカ
オーストリアバリインドニシア
フランスイングランド、スコットランド、アイルランドグリーンランド
ドイツバハマハワイ
ギリシャコロンビア、メキシコ、ペルーアルゼンチン
ニュージーランドロシア米国

そして、DataGridViewが3つの列でセットアップされていて、2番目がコンボボックスであるとしましょう。

ここに画像の説明を入力してください

グリッドにデータを入力し、コンボボックス列に誤ってデータを入力すると、エラーが発生します。

これを解決する方法は、DataErrorイベントを「明示的に処理/宣言」し、さらに重要なことに、コンボボックス列に正しく入力することです。

private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
    //Cancelling doesn't make a difference, specifying the event avoids the prompt 
    e.Cancel = true;
}

private void dataGridView2_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
    e.Cancel = true;
}

したがって、2番目の列に国のドロップダウンリストが含まれ、1番目と3番目の列にテキストフィールドが含まれていると想像してください。

1列目と3列目は単なる文字列なので、各行を表すクラスを作成します。

public class CountryData
{
    public string FirstCountry { get; set; }
    public string ThirdCountry { get; set; }
}

2列目の「国」コンボボックスセルについては、2列目のデータソースにバインドするため、別のクラスを作成しました。

public class MultiCountryData
{
    public string[] SeceondCountryOption { get; set; }
}

ここに示すように、グリッドにコンボボックス列などを追加します:https ://stackoverflow.com/a/1292847/495455は良い習慣ではありません。ビジネスロジックをプレゼンテーションから分離して、単体テストとメンテナンスを容易にする、よりカプセル化された多態的で抽象的なアプローチを実現したいと考えています。したがって、DataBinding。

コードは次のとおりです。

namespace BusLogic
{
public class ProcessFiles
{

internal List<CountryData> CountryDataList = new List<CountryData>();
internal List<MultiCountryData> MultiCountryDataList = new List<MultiCountryData>();

internal void foo(string path,string choosenFile)
{
    var custIndex = new List<int>();
    //if (choosenFile.Contains("Cust"))
    //{
        var lines = File.ReadAllLines(path + "\\" + choosenFile);
        foreach (string line in lines)
        {
            int errorCounter = 0;
            string[] items = line.Split('\t');

            //Put all your logic back here...

            if (errorCounter == 0)
            {
                var countryData = new CountryData()
                                      {
                                          FirstCountry = items[0],
                                          ThirdCountry = items[2]
                                      };
                countryDataList.Add(countryData);

                multiCountryDataList.Add( new MultiCountryData() { SeceondCountryOption = items[1].Split(',')});

            }
        //}
      }

}
}

プレゼンテーションプロジェクトでは、ボタンクリックコードは次のとおりです。

 imports BusLogic;
 private void button1_Click(object sender, EventArgs e)
 {
     var pf = new ProcessFiles();
     pf.foo(@"C:\temp","countries.txt"); 
     dataGridView2.AutoGenerateColumns = false;
     dataGridView2.DataSource = pf.CountryDataList;
     multiCountryDataBindingSource.DataSource = pf.MultiCountryDataList;      
 }

dataGridView2.AutoGenerateColumns = false;設計時に3列を追加したので設定しました。1番目のテキスト列、2番目のコンボボックス列、および3番目のテキスト列。

2番目のコンボボックス列をバインドするコツはBindingSourceです。設計時に>DataGridViewを右クリック>[列の編集]を選択>2番目の列を選択>[データソース]を選択>[プロジェクトデータソースの追加]をクリック>[オブジェクト]を選択>次にmultiCountryクラスにチェックマークを付けて[完了]をクリックします。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

また、1番目の列のDataPropertyNameをFirstCountryに設定し、3番目の列のDataPropertyNameをThirdCountryに設定して、データをバインドするときにマッピングが自動的に行われるようにします。

ここに画像の説明を入力してください

最後に、BindingSourceのDataMemberプロパティをmultiCountryクラスのSeceondCountryOptionメンバーに設定することを忘れないでください。

ここに画像の説明を入力してください

これがコードデモですhttp://temp-share.com/show/HKdPSzU1A

于 2012-12-07T23:40:19.593 に答える