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

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

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

Re[5]: デリゲート?


(過去ログ 133 を表示中)

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

■78847 / inTopicNo.1)  デリゲート?
  
□投稿者/ マティ (1回)-(2016/02/21(Sun) 11:15:37)

分類:[VB.NET/VB2005 以降] 

Form1にTextbox1とComboBox1を配置して
ComboBox1の表示内容を変更する度にTextBoxの表示も変わるという単純なものですが、
ComboBox1のアイテムを増やす度にselectの分岐も増やしていくのが、すこし野暮ったいような気がします。

例えばComboBox1.Items.Add("え")を追加して TextBox1.Textに 「え」を表示させるとして
Select Caseの分岐を増やさない方法はあるでしょうか?
デリゲートやラムダ式を使えばいいのでしょうか?
ご教示よろしくお願いします。


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ComboBox1.Items.Add("あ")
        ComboBox1.Items.Add("い")
        ComboBox1.Items.Add("う")
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged

        Select Case ComboBox1.SelectedItem.ToString
            Case "あ"
                TextBox1.Text = "あ"
            Case "い"
                TextBox1.Text = "い"
            Case "う"
                TextBox1.Text = "う"
        End Select
    End Sub


引用返信 編集キー/
■78849 / inTopicNo.2)  Re[1]: デリゲート?
□投稿者/ WebSurfer (832回)-(2016/02/21(Sun) 13:09:27)
No78847 (マティ さん) に返信

ComboBox1_SelectedIndexChanged メソッドの中の、

Select Case ComboBox1.SelectedItem.ToString
Case "あ"
TextBox1.Text = "あ"
Case "い"
TextBox1.Text = "い"
Case "う"
TextBox1.Text = "う"
End Select



TextBox1.Text = ComboBox1.SelectedItem.ToString

にすればよさそうな気がするのですが?

引用返信 編集キー/
■78852 / inTopicNo.3)  Re[2]: デリゲート?
□投稿者/ ?}?e?B (1回)-(2016/02/21(Sun) 15:11:29)
ありがとう御座いました。
コンボボックスに表示した文字とテキストボックスに表示する文字が同じだと
WebSurferさんの仰せの通りにするのが良いと思います。

ComboBox1_SelectedIndex メソッドを下記のようにしてForm1_LoadメソッドにComboBox1.Items.Add("え")を追加して TextBox1.Textに "EEE"を表示させる場合 
どうするのがベストでしょうか?

  Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged

        Select Case ComboBox1.SelectedItem.ToString
            Case "あ"
               TextBox1.Text = "AAA"
             Case "い"
                TextBox1.Text = "BBB
            Case "う"
                TextBox1.Text = "CCC"
        End Select
    End Sub

引用返信 編集キー/
■78853 / inTopicNo.4)  Re[3]: デリゲート?
□投稿者/ WebSurfer (834回)-(2016/02/21(Sun) 15:48:06)
No78852 (?}?e?B さん) に返信

「?}?e?B」さん=「マティ」さんですよね? ハンドル名に日本語を使うと化けることが
あるそうですので注意してください。

> ComboBox1.Items.Add("え")を追加して TextBox1.Textに "EEE"を表示させる場合 
> どうするのがベストでしょうか?

ベストかどうかはともかくとして、ComboBox1_SelectedIndexChanged のコードをいちいち
書き直さなくても済むようにするのであれば、"あ", "い", "う", "え" ... を key に、
"AAA", "BBB", "CCC", "DDD" ... を value に持つ辞書を作って、それを使うようにしては
いかがですか?

Dictionary<TKey, TValue> クラス
https://msdn.microsoft.com/ja-jp/library/xfhwa508(v=vs.110).aspx

元データがデータベースにあるような場合は、DataTable を作って使ったほうが簡単かもし
れません。
引用返信 編集キー/
■78860 / inTopicNo.5)  Re[3]: デリゲート?
□投稿者/ 魔界の仮面弁士 (651回)-(2016/02/22(Mon) 04:20:07)
No78852 (?}?e?B さん) に返信
IE や Chrome だと化けないのですが、Firefox だと化けやすいようですね。
cookie の読み書きの際に encode/unencode 等が施されていれば化けないのですが。


> ComboBox1_SelectedIndex メソッドを下記のようにしてForm1_LoadメソッドにComboBox1.Items.Add("え")を追加して TextBox1.Textに "EEE"を表示させる場合 
> どうするのがベストでしょうか?

これでどうでしょう。VB2015 で動作確認。

Public Class Form1
  Private tbl As DataTable
  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    tbl = New DataTable()
    tbl.Columns.Add("Col1")
    tbl.Columns.Add("Col2")
    tbl.Rows.Add("あ", "AAA")
    tbl.Rows.Add("い", "BBB")
    tbl.Rows.Add("う", "CCC")
    ComboBox1.Items.Clear()
    ComboBox1.DataSource = tbl
    ComboBox1.DisplayMember = "Col1"
    TextBox1.DataBindings.Clear()
    TextBox1.DataBindings.Add("Text", tbl, "Col2")
  End Sub

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    tbl.Rows.Add("え", "EEE")
  End Sub
End Class
引用返信 編集キー/
■78864 / inTopicNo.6)  Re[3]: デリゲート?
□投稿者/ WebSurfer (836回)-(2016/02/22(Mon) 12:25:56)
No78852 (?}?e?B さん) に返信

上の私のレスで書いたことの具体例を書いておきます。

辞書(Dictionary<string, string> クラス)を作って使う場合の例。項目が増えた場合は
Dictionary メソッドだけ修正すれば OK です。さらに、外部のテキストファイル等から項
目を取得するようにすれば、コードはいじらなくても外部テキストファイルのみ修正すれば
OK です。

namespace WindowsFormsApplication
{
    public partial class Form11 : Form
    {
        Dictionary<string, string> dictionary;
        
        public Form11()
        {
            InitializeComponent();

            this.comboBox2.SelectedIndexChanged += new EventHandler(comboBox2_SelectedIndexChanged);
        }

        private void Form11_Load(object sender, EventArgs e)
        {
            this.dictionary = CreateDictionary();
            this.comboBox2.Items.AddRange(this.dictionary.Keys.ToArray());
            this.comboBox2.SelectedIndex = 0;
        }

        // 辞書を作るためのヘルパメソッド
        private Dictionary<string, string> CreateDictionary()
        {
            Dictionary<string, string> dictionary = new Dictionary<string, string>();
            dictionary.Add("あ", "AAA");
            dictionary.Add("い", "BBB");
            dictionary.Add("う", "CCC");
            dictionary.Add("え", "DDD");
            // 以降必要な分を追加
            return dictionary;
        }

        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.comboBox2.SelectedIndex != -1)
            {
                this.textBox2.Text = dictionary[((ComboBox)sender).SelectedItem.ToString()];
            }
        }

    }
}

上記より、もし ValueMember に "AAA", "BBB", "CCC", "DDD"... を設定して良いなら、わ
ざわざ辞書を作る必要はなくなりますので、その方がスマートにできると思います。


さらに、上のレスにも書きましたが、元データがデータベースにあるような場合は、Visual
Studio のウィザードを使って 型付 DataSet/DataTable + TableAdapter を自動生成させて
それを使ったほうが簡単かもしれません。以下のような感じです。

namespace WindowsFormsApplication
{
    public partial class Form11 : Form
    {
        NorthwindDataSet dataset;
        NorthwindDataSetTableAdapters.CustomersTableAdapter tableAdaptor;

        public Form11()
        {
            InitializeComponent();

            this.dataset = new NorthwindDataSet();
            this.tableAdaptor = new NorthwindDataSetTableAdapters.CustomersTableAdapter();

            this.comboBox1.SelectedIndexChanged += new EventHandler(comboBox1_SelectedIndexChanged);
        }

        private void Form11_Load(object sender, EventArgs e)
        {
            this.tableAdaptor.Fill(this.dataset.Customers);

            // DataSource の設定は最後にすること。最初に持ってくると、DisplayMember、
            // ValueMember の設定時に余計なデータバインドが起こる。
            this.comboBox1.DisplayMember = "CustomerID";
            this.comboBox1.ValueMember = "CompanyName";
            this.comboBox1.DataSource = this.dataset.Customers;
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.comboBox1.SelectedIndex != -1)
            {
                this.textBox1.Text = ((ComboBox)sender).SelectedValue.ToString();
            }
        }
    }
}

引用返信 編集キー/
■78868 / inTopicNo.7)  Re[4]: デリゲート?
□投稿者/ マティ (2回)-(2016/02/22(Mon) 16:38:46)
WebSurferさん
お返事ありがとうございました。
こちらのC#のコードでの投稿があったのを知らず、Dictionaryクラスを調べ自分なりにコードを作成したのですが
以下のようになりました。
Dictionaryクラスは知らなかったので調べてみましたら、連想配列のことなんですね(使ったことはないですが)
こうするとで ComboBox1_SelectedIndexChanged メソッド内で分岐を使わわずに済むんですね。
スッキリしました。

当方のコードに比べてWebSurferさんのコードは汎用的で実用的ですね。
メソッドにしたデータ部の呼び出し方法はとても参考になります。


    Dim dict As New Dictionary(Of String, String)

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        dict("あ") = "AAA"
        dict("い") = "BBB"
        dict("う") = "CCC"
        dict("え") = "DDD"

        ' コンボボックスに表示
        For Each v As String In dict.Keys
            ComboBox1.Items.Add(v)
        Next
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged

        TextBox1.Text = dict(ComboBox1.SelectedItem)

    End Sub



>>Studio のウィザードを使って 型付 DataSet/DataTable + TableAdapter を自動生成させて
>>それを使ったほうが簡単かもしれません。以下のような感じです。

こういった機能もあるのですね。勉強してみます。
この度はご教示ありがとうございました。

解決済み
引用返信 編集キー/
■78869 / inTopicNo.8)  Re[5]: デリゲート?
□投稿者/ マティ (3回)-(2016/02/22(Mon) 16:55:46)
魔界の仮面弁士 さん
お返事ありがとうございました。

こちらのコードですと、Button1_ClickでDataTableに文字列を追加しているだけで目的の動作が可能なんですね。
ComboBox1_SelectedIndexChangedメソッドと分岐を使わなくてもここまで出来るのですね。

さすがに上級者のコードにには無駄がないですね。
WebSurferさん、魔界の仮面弁士さんのお二方にはコードまで提示して頂き
とても勉強になりました。
この度はありがとうございました。

解決済み
引用返信 編集キー/


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

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -