プロが教えるわが家の防犯対策術!

.NETでWinFormアプリをC#で製作中です。
Visual Studio Community 2017を使用しています。

デフォルト設定ではDataGridViewの列ヘッダーをクリックすると行を並び変えできますが、表示上だけでバインドしているDataTableには影響がないかと思います。

私がやりたいのは、列ヘッダーをクリックするとDataTableの値をソートしてその結果をDataGridViewに反映(つまり表示を更新)させたいのですが、苦戦しています。

FormとDataSetとDataTableは、添付図のように全てForm Designerで作成・設定したのでそちらはコーディングしていません。

その上で下記のように記述して、ボタンを押すとソートができるところまでは辿りつきました。
しかしDataGridView上でのみソートされているようです。
(試しにDataTableをテキストファイルに書き出すメソッドで確認してもDataTableは元の値のままでした)

private void Form1_Load(object sender, EventArgs e)
{
// テーブルにデータを追加
//タスクテーブルBindingSource.Add("要望", "レベル", "低", "進行中");
studyDataSet.studyTable.Rows.Add("数学", 80, "鈴木");
studyDataSet.studyTable.Rows.Add("国語", 40, "田中");
studyDataSet.studyTable.Rows.Add("社会", 60, "田中");
studyDataSet.studyTable.Rows.Add("英語", 70, "鈴木");
studyDataSet.studyTable.Rows.Add("数学", 80, "田中");
studyDataSet.studyTable.Rows.Add("英語", 90, "田中");
studyDataSet.studyTable.Rows.Add("国語", 80, "鈴木");
studyDataSet.studyTable.Rows.Add("社会", 60, "鈴木");
}

// ボタン「Sort」を押す
private void button1_Click(object sender, EventArgs e)
{
DataView dv = new DataView(studyDataSet.studyTable);
dv.Sort = "教科 ASC";
this.dgv.DataSource = dv.ToTable();
}

// 関数:表データを出力する
private void SaveTaskData()
{
// 出力ファイル名
string path = "data.txt";
// 1行分のデータ
string strData = "";

// 出力設定
StreamWriter sw = new StreamWriter(
path,
false, // 追記ではなく上書き
Encoding.Default);

// 表の一行の値をカンマ区切りで一行の文字列にしていく
foreach (studyDataSet.studyTableRow drTask
in studyDataSet.studyTable)
{
strData = drTask.教科 + ","
+ drTask.点数 + ","
+ drTask.名前 + ",";

// 一行書き込み
sw.WriteLine(strData);
}
sw.Close();
}

「DataTable ソート」等で検索すると沢山ヒットはしますし、色々と見てはみたのですが今一つ答えがストレートに書いてある情報に辿りつけませんでした。。

結局のところどのように記述すれば良いのでしょうか?

アドバイスありましたらぜひお願いします。m(_ _)m

「C# DataTableの行をソートして」の質問画像

質問者からの補足コメント

A 回答 (1件)

>>私がやりたいのは、列ヘッダーをクリックするとDataTableの値をソートしてその結果をDataGridViewに反映(つまり表示を更新)させたいのですが、苦戦しています。



いままで仕事でDataGridViewを扱うプログラムをいろいろ見たことありますが、質問者さんのやりたいような機能を実現しているプログラムはゼロです。
一般的に、DataGridView上での並びは変えたいけど、DataTableつまりは、Databaseのデータの並びは仕組み的に変えられないからです。

もし、画面上で変えた並び順のデータをDataTableに書き戻したいなら、DataTableの中身を一度消して、DataGridViewからDataTableに新しく書き込むといいと思います。
    • good
    • 0
この回答へのお礼

lv4uさんご回答ありがとうございます!

>質問者さんのやりたいような機能を実現しているプログラムはゼロです。

そうなのですね‥!
そもそも私がそうしたいと思ったのは異端な考えだったんですね、、

なぜそうしたいと思ったかというと、DataGridViewの標準機能のヘッダークリックによる自動ソートを使用すると、アプリ起動時にソート中に新しくRow.Addすると最後の行じゃなくソートが反映された位置に追加されて、どこに追加されたのか分からなくなって不便に感じたからです。
(これは当然の挙動とも思いますし便利とも思うのですが)

加えて、1つ前にソートした結果を保って新しい列をソートしてくれないからです。
(A列を昇順ソートした後にB列を昇順ソートしたら、B列が同じ値ならA列の値は昇順に並んだままにして欲しい)
自前のソートであれば引数で列を二つ選んでのソートが可能なようなので、一つ前にソートした列を覚えさせておいて自前でソートさせる方が良さそうですね。。

それから、一度ヘッダークリックしてしまうと自動ソートをやめること(エクセルで言う”並べ替えとフィルタ”のクリア)もできないですが、登録順に番号を振った列を先頭にでも追加してやれば登録順に戻せるようにするのも容易だなと思いました。

その上で本当にDataTableを並び変える必要があるのか今一度見直したいと思います。
やっぱり並び変えをDataTableに戻してやりたいと思ったら、アドバイスいただいた方法でやってみたいと思います!

お礼日時:2018/10/04 09:56

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A