C#、listboxについての質問です。

二つのリストボックスがあるとします。
・listBox1
・listBox2

listBox1にはアイテムが複数セットされている状態です。
アイテムが選択されいている状態でrightbuttonをクリックすると
listBox2にアイテムが移動します(lisytBox1でそのアイテムはremove)

もしかしたら間違えてlistBox2に移動する可能性もあるので2から1へ
アイテムを戻すlefghtbuttonも用意します。

そこで質問です。
そのときに2から1へ戻ったとき、普通にAdd()するのではなく、移動する前の状態の位置に戻したいのです。

普通にやると末端に追加されます。

ロジックが思いつきません。
お力添えのほどよろしくお願いいたします。

A 回答 (4件)

listBox1に追加するオブジェクトに,本来の並び順を保持させておいて,


戻す時にはオブジェクトの並び順を見てInsertする位置を決めればよいでしょう。

ListBoxに追加できるのは文字列だけでなく,どんなオブジェクトでも追加できます。
また,要素の表示はListBoxのDisplayMemberで決定されますが,DisplayMemberを指定していない場合はToStringが使われます。

なので,
class Item : IComparable<Item>
{
public Item (string display, int defaultOrder)
{
Display = display;
DefaultOrder = defaultOrder;
}

public string Display { get; private set; }
public int DefaultOrder { get; private set; }

int IComparable<Item>.CompareTo (Item other)
{
if (other == null) { return 1; }
return DefaultOrder.CompareTo(other.DefaultOrder);
}

public override string ToString ()
{
return Display;
}
}
というようなクラスを作り,このItemクラスをlistBox1, listBox2の要素としておけば,
var pos = listBox1.Items.Cast<Item>().ToList().BinarySearch(addItem);
if (pos < 0) { pos = ~pos; }
listBox1.Items.Insert(pos, addItem);
で戻すことができます。
    • good
    • 0

というワケで…簡単に作ってみました。


検証不十分と思われますので、地道に検証してくださいな。

ちなみに、プロパティでbutton1(rightbutton相当)とbutton2(lefghtbutton相当)のEnabledはfalseに、
listBox1のItemsにはあらかじめデータ入れておいてください。
あと、全角空白でインデントしていますのでよろしく処理してください。
コメントも特に入れていないので自力で読んでください。

public partial class Form1 : Form
{
 private Stack<MoveItemHistory> History;
 public Form1()
 {
  InitializeComponent();
  History = new Stack<MoveItemHistory>();
 }
 private void button1_Click(object sender, EventArgs e)
 {
  MoveItemHistory temp = new MoveItemHistory();

  temp.Index = listBox1.SelectedIndex;
  temp.ItemString = (string)listBox1.Items[temp.Index];
  listBox2.Items.Add(temp.ItemString);
  listBox1.Items.RemoveAt(temp.Index);
  listBox1.SelectedIndex = -1;
  History.Push(temp);
  button2.Enabled = true;
 }
 private void button2_Click(object sender, EventArgs e)
 {
  MoveItemHistory temp = History.Pop();

  button2.Enabled = (History.Count > 0);
  listBox2.Items.Remove(temp.ItemString);
  listBox1.Items.Insert(temp.Index, temp.ItemString);
 }
 private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
 {
  button1.Enabled = (listBox1.SelectedIndex != -1);
 }
}
public class MoveItemHistory
{
 public int Index;
 public string ItemString;
}
    • good
    • 0

>そうするとlistBox1の5番目[りんご]


>をlistBox2に移動し、他のアイテムも複数移動したら
>listBox1の配列のCountは(例えば)2つとかになりますよね。
>listBox2からlistBox1に戻すときに5番目、(移動するときに持っていたindex=5)にインサートしたら、配列範囲外になりませんか?

だから、「最後の1つだけ…とか制限付くと思いますけども。」と書いたのですが……。

そういう制限なしでやりたいというのであれば、履歴を持ち続けるしかないでしょうね。
で、lefghtbuttonのたびに履歴から操作することに。
# 履歴を格納する構造体なり作って、List構造として記録…でしょうかねぇ。
# List<T>とかで。
# スタック構造でもいいのか…そういうのがあったかはちょっと不明ですが。
# 「C# アンドゥ 実装」辺りで検索するとよさげなものが見つかるかも知れませんね。
    • good
    • 0

>そこで質問です。


>そのときに2から1へ戻ったとき、普通にAdd()するのではなく、移動する前の状態の位置に戻したいのです。

ListBox.Items.Insert()ですかね。

最後の1つだけ…とか制限付くと思いますけども。
rightbuttonで移動(というかlistBox1から削除)する前にインデックスを記憶…
lefghtbuttonで戻す時に記録していたインデックスを元にInsert()
ってところでしょうかね。

listBox1の先頭のアイテムや最後のアイテムだった場合に正しく動作するか?
というのはちゃんと確認してくださいな。

この回答への補足

listBox1の総数を5こだとします。
そうするとlistBox1の5番目[りんご]
をlistBox2に移動し、他のアイテムも複数移動したら
listBox1の配列のCountは(例えば)2つとかになりますよね。
listBox2からlistBox1に戻すときに5番目、(移動するときに持っていたindex=5)にインサートしたら、配列範囲外になりませんか?

また、listbox1から2へいくつか移動した後から戻したとすると、
indexは混同しませんか?

という感じで悩んでおります。。。
未熟者故、うまいロジックが思いつかないのです。

せっかく教えて下さったのですが、今一度お力添えをお願いいたします><

補足日時:2014/08/20 16:31
    • good
    • 0

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC#です。リストボックスの項目をダブルクリックすると、別のフォーム出現するには

C#です。初心者です。

リストボックスの項目をダブルクリックすると、別のフォーム出現するようにしたいのですが。

どのようにプログラムを書いたらできるのでしょうか??

教えてくれませんか??
お願いします。

Aベストアンサー

Formのロードの部分など(デザイナでフォームの余白をダブルクリックで生成されます)で、DoubleClickイベントを登録します。

listBox1.DoubleClick += new EventHandler(listBox1_DoubleClick);

↑のような感じですが、+=を書いた時点でイベントや、残りの文が自動生成されます。

void listBox1_DoubleClick(object sender, EventArgs e)
{
throw new NotImplementedException();
}

生成されるイベントはこのようになります。
これはリストボックスがダブルクリックされた際に実行されるメソッドになります。
この中のthrow文を削除かコメントアウトして、自分の書きたい処理を書けばOKです。
(この場合は new SomeForm().Show(); などでしょうか?)

また、
if(listBox1.SelectedIndex != -1){
// 何らかの処理
}
としておけば、「何も選択されていない状態では処理を行わない」といったことができます。
C#を始めたばかりの頃ハマりましたので一応補足しました。
SelectedIndexプロパティには選択されたアイテムの番号(0~)が入っていますので、選択によって処理を変化させたいときに使えます。

Formのロードの部分など(デザイナでフォームの余白をダブルクリックで生成されます)で、DoubleClickイベントを登録します。

listBox1.DoubleClick += new EventHandler(listBox1_DoubleClick);

↑のような感じですが、+=を書いた時点でイベントや、残りの文が自動生成されます。

void listBox1_DoubleClick(object sender, EventArgs e)
{
throw new NotImplementedException();
}

生成されるイベントはこのようになります。
これはリストボックスがダブルクリックされた際に実行されるメソ...続きを読む

QC# ListBoxのキーボードマッチを無効にしたい

お世話になります。
.NET FW2.0+C#でListBoxを使用しています。

ListBox(ドロップダウンリスト)にはフォーカスしている状態でキーボードの英数キーを押すとリスト内のValue先頭値と自動的にマッチするものを選択状態とする機能が標準で備わっていますが、これを無効とする方法はありますでしょうか。

プロパティでは該当するものがなかったようです。
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.listbox_properties(VS.80).aspx#

イベント処理で何とかするしかないのでしょうか。それともプロパティの見落としか・・・・

可能であれば方法など教えて頂けると助かります。

Aベストアンサー

ListBoxのKeyPressイベントを処理するようにしましょう

イベントハンドラを
private void listBox1_KeyPress(object sender, KeyPressEventArgs e)
{
  // キーは処理済ですといったことになる
  e.Handled = true;
}
といった具合で定義しておきます

this.listBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.listBox1_KeyPress);
といった具合で イベントハンドラをInitializeComponentなどで接続します

QC#でテキストボックスをクリック→フォームが開く→フォームで設定した値

C#でテキストボックスをクリック→フォームが開く→フォームで設定した値を元のテキストボックスに入力

こんな感じのことをC#でやりたいのですがよくわからないので教えてください。

1. 親をForm1、子をForm2とします

2. Form1のTextBox1をクリックするとForm2が開いきます

3. Form2で設定した値をForm2の「入力」ボタンを押すとForm2が閉じてTextBox1に値が入力されます

というものです。
ここで、textBoxは「クリックしたコントロール名を取得してForm2に渡したい」のです。
テキストボックスがたくさんあるので、textBox1とか決まった名前ではありません。
この部分がわからないのです。

-------------------------------------------------------
Form1:
private void textBox1_Click(object sender, EventArgs e)
{
 Form2 fromItem = new Form2(sender);
 DialogResult deRet = fromItem.ShowDialog();
}

Form2:
public Form2(object sender)
{
 InitializeComponent();
 object pSender = sender;
}

private void button_input_Click(object sender, EventArgs e)
{
 ((System.Windows.Forms.TextBox)pSender).text = "hoge";
}
-------------------------------------------------------

この程度しかわかりません。
正しい方法を教えてください。よろしくお願いいたします。

C#でテキストボックスをクリック→フォームが開く→フォームで設定した値を元のテキストボックスに入力

こんな感じのことをC#でやりたいのですがよくわからないので教えてください。

1. 親をForm1、子をForm2とします

2. Form1のTextBox1をクリックするとForm2が開いきます

3. Form2で設定した値をForm2の「入力」ボタンを押すとForm2が閉じてTextBox1に値が入力されます

というものです。
ここで、textBoxは「クリックしたコントロール名を取得してForm2に渡したい」のです。
テキストボックスがたくさんある...続きを読む

Aベストアンサー

Form2の側を少し直します。

object pSender; // 追加

public Form2(object sender)
{
InitializeComponent();
pSender = sender; // 追加
//object pSender = sender; // 削除。これだとpSenderが他から見れません
}

private void button_input_Click(object sender, EventArgs e)
{
// textじゃなくてText
((System.Windows.Forms.TextBox)pSender).Text = "hoge";

//以下は追加で試してみました。
//MessageBox.Show(((System.Windows.Forms.TextBox)pSender).Name);
//MessageBox.Show(((System.Windows.Forms.TextBox)pSender).Parent.Name);
//this.Close();
}

Form2の側を少し直します。

object pSender; // 追加

public Form2(object sender)
{
InitializeComponent();
pSender = sender; // 追加
//object pSender = sender; // 削除。これだとpSenderが他から見れません
}

private void button_input_Click(object sender, EventArgs e)
{
// textじゃなくてText
((System.Windows.Forms.TextBox)pSender).Text = "hoge";

//...続きを読む

QC# LISTBOXの複数項目取得

お世話になります。
WindowsFormで、リストボックスを使い開発をしています。
状況としては、Bindingsourceとデータセットを使用し、検索してきたものを表示。
この時、DisplayMenberとValueには違う値を設定しています。
やりたいことは
ボタンクリック時に、複数選択している項目のValueを取得したいと思っています。
よろしくお願いします。

Aベストアンサー

確かに、これはわかりにくいですね・・・。

using System;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;

namespace CsListBoxTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
this.table1TableAdapter.Fill(this.tESTDataSet2.Table1);
}

private void button1_Click(object sender, EventArgs e)
{
foreach (DataRowView drv in listBox1.SelectedItems)
{
Debug.WriteLine(drv.Row.ItemArray[1]);
}
}
}
}

確かに、これはわかりにくいですね・・・。

using System;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;

namespace CsListBoxTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
this.table1TableAdapter.Fill(this.tESTDataSet2.Table1);
}

private void button1_Click(object sender,...続きを読む

QC#のフォームプログラミングを解説した本

自分は「猫でもわかるC#プログラミング」という本を購入し、ゲームを作成するためにC#を勉強しようとしたのですが、全部読んでみてもコンソールだけで、GUIアプリケーション、C#ではフォームと言うらしいですが、その解説はありませんでした。
そこでC#のフォームプログラミングを解説した良書を購入し、勉強したいと思っています。しかしamazonなどの書籍の解説などを見ても、CUIなのかフォームの事が書かれているのかいまいち分かりません。もし、C#のフォームプログラミングを解説している本で、分かりやすい初心者向けの書籍をご存知の方おられましたら、書籍名を教えて頂けると幸いです。

Aベストアンサー

本はわかりませんが、C#のフォーム入門サイトを紹介します。

入門サイト。
http://www.wisdomsoft.jp/dev/api/dotNet/forms
「Windows Program」をお読みください。
http://www13.plala.or.jp/kmaeda/cs/cs.html

C#のTIPS集です。
http://athomejp.com/goldfish/vcs/
http://uchukamen.com/index-category.htm
http://www.geocities.co.jp/SiliconValley-Sunnyvale/6810/tips/form/index.htm

一冊見つけたので貼っておきます。
http://www.ascii.co.jp/books/books/detail/4-7561-4845-X.shtml

QC,C++,VB,Java 各言語の特徴って何ですか?

C,C++,VB,Java これらの各言語の特徴や開発にあたって注意しないといけない点などを教えてください。

■背景
現行のシステムには様々な開発言語が用いられていますが、時々なぜこのシステムを開発するのにこの言語を使ったんだろう?と思うことってありませんか?
私は試行錯誤すればどの言語でも大抵のことはできると思っているせいか、いまいち言語の特徴が明確にできません。
上記の言語を比較してそれぞれどのようなことが言語の特徴となるのでしょうか?
よろしくお願いいたします。

Aベストアンサー

C言語……元々UNIXを開発する為に作られた。OS開発言語。俗に「高級アセンブリ」等と呼ばれる。開発当時のレベルでは「プラットフォーム間の差異を吸収する」移植性の高い言語だった。
これは元々UNIX自体が特定の「動作可能/保証するプラットフォームを持たなかった」為である。「移植性の高いOS」を作るための「移植性の高い言語」が開発目的の一つだった。
Algol等の「構造型プログラミング」の考え方を基盤としている。そして元々日常ユースは想定されていないし、「大きくて複雑なプログラム」を書く為のモノでもなかった。
UNIXの開発思想は「一つの目的の為の小さなプログラム」の集合体だった筈だが別のプラットフォームで大きくて複雑なプログラムを書く事に使われ初め当初の使用目的と大きく乖離していった。一つの背景に、貧弱なマシンでスピードを稼ぐには「C言語しか選択肢が無い」と言う状況が続いた為と思われる。
なお、C言語のコンパイラの最適化は他の言語を上回るケースが多く、現在ではOSの他に、Lisp、Perl、Python、Ruby等の「言語を書く為の言語」として使われるケースが多い。元々、プログラミング言語はアセンブリ言語で組み立てられるケースが多かったが、現時点その分野も前述の特徴の為、C言語に置き換わってる。

C++…基本的にはC言語にSimulaと言う言語の特徴を付け加えたモノ。最初はObjective CとかC with Classes等と呼ばれた。ただし、ここで言う「オブジェクト指向」は元々オブジェクト指向、と名乗ったSmalltalkの概念とは(被る分もあるものの)大幅に異なる。

Squeak(Smalltalk):
http://squeakland.jp/

また、厳密には「オブジェクト指向」を表す定義も存在しない。ただし、C++がポピュラーになるにつれて「C++型の」オブジェクト指向が受け入れられた。
C++は必ずしも「より良いC」は意味しない。元々のデザイナーであるStroustrupによる冗談も存在する。

http://hp.vector.co.jp/authors/VA000092/jokes/strup.html

VB……本家BASICとはかなりかけ離れたMicrosoftのプロプリエタリ言語。ただし、「Windowsで動くソフトを作る」分には最強の能力を発揮する、と思われる。また、BASICとしては最高、との評もある。
「VBのオブジェクト指向は本格的ではない」等と言った批判もあるが、前述のように元々「オブジェクト指向」自体の定義が曖昧な為、割に見当違いの批判だと思われる。
ただし、C言語やC++みたいに移植性は念頭に置いてない。また、本家BASICともコードの互換性はほぼ無い。

Java……一言で言うと改良版C++。開発者のジェームス・ゴスリングもそう述べている。提供元はSun Microsystems。
あまりに低レベル(アセンブリに近い)なC言語特有の操作(具体的にはポインタ)を止め、メモリ管理をガベージ・コレクション(ゴミ集め)に任せてる。これでプログラマがメモリ管理に頭を悩ます事が無くなった。
また、登場した70年代と違い、C言語の「移植性の利点」が薄れてきた事もあり、もう一段階上のレベルでの移植性を達成するように作られている。かいつまんで言うと、OS上の「Java仮想マシン」で動く言語、と言う構図になっている。言い換えると「コンピュータ上で動くコンピュータ」で動くアプリケーションが作れる、と言うのが特徴。プラットフォームの差はその「仮想マシン」で吸収される。
従って、CやC++等と違い、Javaのソースはネイティブコードにはコンパイルされないで仮想マシン上で動く中間コードへとコンパイルされる。
移植性はピカイチだが、反面、Java製のアプリは「コンピュータ上で動くコンピュータ」上で動く為、スピードの面で言うとCやC++で作成されたアプリに劣る、と言う欠点も持ち合わせている(ただし、色々なエミュレータなんかを見ても分かるように、近年はハードウェアの進歩により、そこまでスピードは問題では無くなって来た)。

C言語……元々UNIXを開発する為に作られた。OS開発言語。俗に「高級アセンブリ」等と呼ばれる。開発当時のレベルでは「プラットフォーム間の差異を吸収する」移植性の高い言語だった。
これは元々UNIX自体が特定の「動作可能/保証するプラットフォームを持たなかった」為である。「移植性の高いOS」を作るための「移植性の高い言語」が開発目的の一つだった。
Algol等の「構造型プログラミング」の考え方を基盤としている。そして元々日常ユースは想定されていないし、「大きくて複雑なプログラム」を書く為のモノ...続きを読む

QC#でバイナリデータをテキストフォームへ表示させるには?

C#でバイナリデータをテキストフォームへ表示させるには?

C#でバイナリファイルをテキストへ変換するツールを作成しています。
バイナリデータを配列へ格納し、その配列をテキスト変換してテキストフォームへ出力させるという処理を作成したいのですが、どうすれば良いのかどうしてもわかりません。

どのようなコードをどのようにして書けばよいのか、ご教示いただけないでしょうか。
よろしくお願いします。

(ちなみにC#を始めて1週間ほどです)

Aベストアンサー

下記のURLご参照ください。

参考URL:http://yellow.ribbon.to/~tuotehhou/index.php?CSharp0001

QWinアプリ(c#) webアプリ(c#.net) とは?

4月から社会人になります。
職種はシステムエンジニアです。
社員十数名ほどの小さな会社で、研修はありません。

何かやっておいた方がいい事はないか質問すると、
「Winアプリ(c#)やwebアプリ(c#.net)あたりをやっておくといいかもしれない。」
との事で、とりあえずC#の入門書を買ってみたのですが、
わからない事だらけで困っています。
超初心者なので、細かく教えて頂けないでしょうか。

(1)Winアプリ・webアプリとは何ですか。
(2)C#とC#.netは同じなのですか。違うのなら、C#.netとは何ですか。
(3)C#とはVisual C#の事ですか?

その他知っておくべき事等お教え頂ければ幸いです。
宜しくお願い致します。

Aベストアンサー

>(1)Winアプリ・webアプリとは何ですか。
WinアプリとはWindowsアプリケーションソフトのこと。
その名のとおりWindowsというOSで動作するアプリケーションソフトのことです。
アプリケーションソフトとは『特定の目的のために作られたソフトウェア』って意味です。

webアプリは、
ブラウザ(IEなど)で動作させるアプリケーションソフトです。
ですので、WindowsというOSに限らずLinuxなど他のOSでもブラウザさえあれば動作します。
このOKWave自体もWebアプリケーションですね。

>(2)C#とC#.netは同じなのですか。違うのなら、C#.netとは何ですか。
同一です。

>(3)C#とはVisual C#の事ですか?
ほぼそう考えてよいと思います。
正確にはVisual C#とはマイクロソフトのVisual Studioを使って、C#という言語で開発するって意味です。


最初はとにかく入門書の内容に従ってプログラムを打ち込んで動かしてみることですね。

QC#のフォームにて

C#のフォームにて

お世話になります。C#のフォームにて
labelに現在の年度を自動で読み取って”2010年度”と
表示させたいのですがうまくいきませんでした。
どなたかご親切な方、お教え頂きたく宜しくお願い致します。

Aベストアンサー

>int nendo;
>if(now.Month >= 4)
>nendo = now.year - 1;
>label1.Text = nendo.ToString() + "年度";

if文に入らない場合nendoの値が初期化されていません。
通常のC言語等だとnendoの値がゴミのままでもそれを値として処理しますが、C#のint型の実態はクラスなので、初期化の有無を判別しているようです。

else文で代入するか、

int nendo = now.Year;

と初期化しておく必要があります。

ちなみに、このソース、if文が間違ってますけど、気付いてますか?

Q【C#】 FormClosingのイベントの追加

C#のプログラミングにて不正な動きをして困っております。
ご存知の方に教えていただきたく思います。
稚拙な質問かも知れませんがご容赦のほど。

【要求】
画面の×ボタン、もしくは終了ボタンが押された時に
確認メッセージを表示して「いいえ」が押されたらフォームを閉じないようにしたいということです。

【構造・実装】
画面構造は、親画面と子画面があり、子画面はモーダルで表示しています。この子画面にFormClosingのイベントを付加しています。

【現象】
(1)親画面起動→終了ボタン押下→メッセージなしで終了
(2)親画面起動→子画面起動→子画面終了ボタン押下→メッセージ表示
 →親画面終了ボタン押下→メッセージ表示
なぜか、子画面に付加したイベントが親画面にも引き継がれているようです。

理由と対処方法をご存知の方がいらっしゃいましたらご教授願います。

Aベストアンサー

ごめんなさい m(__)m ANo.2 の内容は誤りです
とんだ勘違いをしていたようです ・・・

AddOwnedFormの引数は『所有される側のフォーム』でした
ですからこの場合 subFrom が引数になればいいのです

ならばどうして最初の ShowDialogを行った際に親フォームを閉じるときにもsubForm_FormClosingが呼ばれたかといいますと

モーダルで表示したオブジェクト変数を Dispose()で明示的に破棄しなかったのが原因です
隠れたオブジェクトが アプリの中に潜在していて アプリが終了する際に subFormが閉じられようとして メッセージボックスが顕在化したのでしょう

subform_FormCloingの引数eのCloseReasonプロパティでどのような要因でフォームが閉じられようとしているのかを判断しましょう

単純にはsubFromのVisibleプロパティのチェックだけでもよさそうですが


人気Q&Aランキング

おすすめ情報