C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ListBox内で順番を入れ替えたい

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■90239 / inTopicNo.1)  ListBox内で順番を入れ替えたい
  
□投稿者/ c (1回)-(2019/02/19(Tue) 10:09:21)

分類:[.NET 全般] 

DataTableを作成して、ListBoxにDataTableをバインドしています。
やりたい事はフォーム上にアップボタン、ダウンボタンがあり、リストボックス内の
項目を選択して、アップボタンを押すと項目がどんどん上に上がっていくということをやりたいです。

イメージ的にはこんな感じです。
http://1bestcsharp.blogspot.com/2016/08/csharp-listbox-add-remove-item--and-move-up-down.html

DataTableがバインドされているため、当然ながら上記のURLにかかれているように、下記のようなコードは書くことができません。
listBox1.Items.RemoveAt(i);
listBox1.Items.Insert(i - 1, item);
listBox1.SetSelected(i - 1, true);

どのように解決すればよいでしょうか?

using System;
using System.Data;
 
class Program
{
    static void Main(string[] args)
    {
        DataSet dataSet = new DataSet();
        DataTable table = new DataTable("Table");
 
        // カラム名の追加
        table.Columns.Add("教科");
        table.Columns.Add("点数", Type.GetType("System.Int32"));
        table.Columns.Add("氏名");
        table.Columns.Add("クラス名");
 
        // DataSetにDataTableを追加
        dataSet.Tables.Add(table);

		table.Rows.Add("数学", 80, "田中 一郎", "A");
		table.Rows.Add("英語", 70, "田中 一郎", "A");
		table.Rows.Add("国語", 60, "鈴木 二郎", "A");
		table.Rows.Add("数学", 50, "鈴木 二郎", "A");
		table.Rows.Add("英語", 80, "鈴木 二郎", "A");
		table.Rows.Add("国語", 70, "佐藤 三郎", "B");
		table.Rows.Add("数学", 80, "佐藤 三郎", "B");
		table.Rows.Add("英語", 90, "佐藤 三郎", "B");

	   // リストボックスに取得データを設定
	   listBox1.DataSource = table;

       // 表示項目と値のセット
	   listBox1.DisplayMember = "教科";
    }
}

引用返信 編集キー/
■90240 / inTopicNo.2)  Re[1]: ListBox内で順番を入れ替えたい
□投稿者/ 魔界の仮面弁士 (2066回)-(2019/02/19(Tue) 10:26:39)
No90239 (c さん) に返信
> DataTableがバインドされているため、当然ながら上記のURLにかかれているように、下記のようなコードは書くことができません。

並び替え用のフィールドを追加して、
そこに「並べたい順番」に番号を振っていくのが簡単です。


引用返信 編集キー/
■90241 / inTopicNo.3)  Re[1]: ListBox内で順番を入れ替えたい
□投稿者/ 魔界の仮面弁士 (2067回)-(2019/02/19(Tue) 12:18:52)
No90239 (c さん) に返信
> // 表示項目と値のセット
> listBox1.DisplayMember = "教科";

これだと、「誰の」教科かわからないような…。



No90240 (魔界の仮面弁士) に追記
> 並び替え用のフィールドを追加して、
> そこに「並べたい順番」に番号を振っていくのが簡単です。

サンプル。


private void Form1_Load(object sender, EventArgs e)
{
 DataSet dataSet = new DataSet();
 DataTable table = dataSet.Tables.Add("Table");

 table.Columns.Add("教科");
 table.Columns.Add("点数", typeof(int));
 table.Columns.Add("氏名");
 table.Columns.Add("クラス名");

 table.Rows.Add("数学", 80, "田中 一郎", "A");
 table.Rows.Add("英語", 70, "田中 一郎", "A");
 table.Rows.Add("国語", 60, "鈴木 二郎", "A");
 table.Rows.Add("数学", 50, "鈴木 二郎", "A");
 table.Rows.Add("英語", 80, "鈴木 二郎", "A");
 table.Rows.Add("国語", 70, "佐藤 三郎", "B");
 table.Rows.Add("数学", 80, "佐藤 三郎", "B");
 table.Rows.Add("英語", 90, "佐藤 三郎", "B");
 dataSet.AcceptChanges();

 dataSet.EnforceConstraints = false;

 // ソート用に、0 から始まる連番を付与
 table.Columns.Add("SortNo", typeof(int)).AllowDBNull = false;
 for (int rowIndex = 0; rowIndex < table.Rows.Count; rowIndex++)
 {
  table.Rows[rowIndex].SetField<int>("SortNo", rowIndex);
 }

 // 画面表示用の式列を追加する。
 table.Columns.Add("DisplayName", typeof(string), "`教科`+' ('+`クラス名`+'組:'+`氏名`+')'");

 dataSet.EnforceConstraints = true;
 table.AcceptChanges();

 this.listBox1.SelectionMode = SelectionMode.One;
 this.listBox1.DisplayMember = "DisplayName";
 this.listBox1.ValueMember = null;
 this.listBox1.DataSource = new DataView(table, "", "SortNo ASC", DataViewRowState.CurrentRows);

 this.button1.Text = "1 Up";
 this.button2.Text = "3 Up";
 this.button3.Text = "3 Down";
 this.button4.Text = "1 Down";
 this.button1.Tag = -1;
 this.button2.Tag = -3;
 this.button3.Tag = 3;
 this.button4.Tag = 1;

 this.button1.Click += this.UpDownButtons_Click;
 this.button2.Click += this.UpDownButtons_Click;
 this.button3.Click += this.UpDownButtons_Click;
 this.button4.Click += this.UpDownButtons_Click;
}

void UpDownButtons_Click(object sender, EventArgs e)
{
 var offset = ((Control)sender).Tag as int? ?? 0;
 var rowView = this.listBox1.SelectedItem as DataRowView;
 if (offset == 0 || rowView == null) { return; }

 var row = rowView.Row;
 var rows = row.Table.Rows;

 // 新旧の SortNo を求める
 int minSortNo = 0;
 int maxSortNo = rows.Count - 1;
 int oldSortNo = row.Field<int>("SortNo");
 int newSortNo = Math.Min(Math.Max(oldSortNo + offset, minSortNo), maxSortNo);

 // DataTable.Select メソッドに渡す 抽出条件。LINQ で抽出しても良い。
 string filter = string.Format("`SortNo` <> {0} AND `SortNo` >= {1} AND `SortNo` <= {2}",
  oldSortNo,
  Math.Min(oldSortNo, newSortNo),
  Math.Max(oldSortNo, newSortNo));

 var table = row.Table;
 var ds = table.DataSet;
 ds.EnforceConstraints = false;
 DataRow[] movingRows = table.Select(filter, ""); // 加工前に配列に入れておく

 // SoftNo の差し替え
 int d = -Math.Sign(offset);
 Array.ForEach(movingRows, r => r.SetField<int>("SortNo", d + r.Field<int>("SortNo")));
 row["SortNo"] = newSortNo;

 ds.EnforceConstraints = true;
}
引用返信 編集キー/
■90309 / inTopicNo.4)  Re[2]: ListBox内で順番を入れ替えたい
□投稿者/ c (2回)-(2019/02/25(Mon) 15:45:51)
ありがとうございます。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ