none
TextBoxについて RRS feed

  • 質問

  • まずFrom上に静的にテキストボックスとボタンを配置します。
    このテキストボックスを「テキストボックス1」とします。

    次にメンバ変数としてテキストボックスを作成します。
    このテキストボックスを「テキストボックス2」とします。

    次にボタンのクリックイベントで、
    以下のように代入します。
    テキストボックス1 = テキストボックス2

    これで二つのボタンは同じオブジェクトになります。

    次に以下のようにテキストボックス2のTextに値を代入します。
    テキストボックス2.Text = "test";

    予想では、Form上のテキストボックス(テキストボックス1)に"test"と表示されると思ったら
    表示されません。


    基本的なことなのかもしれませんが、予想通りにいかない原因を教えてください。
    よろしくお願いします。

    2011年10月4日 10:05

回答

  • 「テキストボックス1」という変数は、Formに貼り付けてあるTextBoxにつけた名札に過ぎません。

    テキストボックス1 = テキストボックス2
    としても、名札を付け替えただけで、Formに貼り付けてあるTextBoxが移動するわけではありません。

    テキストボックス2= テキストボックス1;
    テキストボックス2.Text="test";
    であればFormに貼り付けてあるTextBoxに「テキストボックス2」という名札をつけたことになり、テキストボックス2という変数を経由してTextを変更することができます。
    あくまで名札をつけただけであり、依然としてテキストボックス1という名札も付けたままなので、テキストボックス1という変数でもテキストボックス2という変数のどちらでもFormに貼り付けてあるTextBoxを操作することできます。

    Fromに貼り付けてある「テキストボックス1」を除去して、「テキストボックス2」を表示させたいということであれば、Form.Controls.Removeで除去して、Form.Controls.Addで追加という処理をする必要があります。

     


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
    • 回答としてマーク Mamezou 2011年10月4日 10:47
    2011年10月4日 10:30

すべての返信

  • 「テキストボックス1」という変数は、Formに貼り付けてあるTextBoxにつけた名札に過ぎません。

    テキストボックス1 = テキストボックス2
    としても、名札を付け替えただけで、Formに貼り付けてあるTextBoxが移動するわけではありません。

    テキストボックス2= テキストボックス1;
    テキストボックス2.Text="test";
    であればFormに貼り付けてあるTextBoxに「テキストボックス2」という名札をつけたことになり、テキストボックス2という変数を経由してTextを変更することができます。
    あくまで名札をつけただけであり、依然としてテキストボックス1という名札も付けたままなので、テキストボックス1という変数でもテキストボックス2という変数のどちらでもFormに貼り付けてあるTextBoxを操作することできます。

    Fromに貼り付けてある「テキストボックス1」を除去して、「テキストボックス2」を表示させたいということであれば、Form.Controls.Removeで除去して、Form.Controls.Addで追加という処理をする必要があります。

     


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
    • 回答としてマーク Mamezou 2011年10月4日 10:47
    2011年10月4日 10:30
  • 迅速な返信ありがとうございます。

    返信して頂いた内容を落ち着いて読ませて頂いたら、理解することができました。

    テキストボックス1 も テキストボックス2 も別々のメモリ上に存在しているんですね。
    テキストボックス1 = テキストボックス2 としたところで
    両方ともテキストボックス2のオブジェクトを参照しているのですね。

    自分の思っていた予想が今思うと恥ずかしい限りです。


    Form.Controls.RemoveとForm.Controls.Addの方法も参考になりました。
    どうもありがとうございます。

    2011年10月4日 10:47
  • 外池と申します。

    gekkaさんのご回答にケチをつけるわけではないのですが・・・、
    いや、すいません、結局ケチつけることになるか・・・、
    ちょっと、ご説明が大雑把すぎるような気がしたので、補足させてください。

    以下の3つを区別して理解する必要があります。

    1. Formに貼り付けたTextBoxは、ちゃんと「実体」があります。Textプロパティーに文字列を代入すれば、ちゃんと表示されます。「実体」のことを「インスタンス」と言います。(テキストボックス1と「名前」をつけた、とされていますが、「インスタンス」と「名前」の関係は一旦忘れてください。次で説明します。)
    2. テキストボックス1は、TextBoxのインスタンス(実体)を指し示す変数の名前に過ぎません。TextBoxのインスタンスがいくつもあるのであれば、どれを指し示すこともできます。今回、テキストボックス1が、Formに貼り付けたTextBoxの実体を指し示している理由は、FormにTextBoxを貼り付けた際に、そうなるように、Visual Studioが自動的にプログラムを書き込んでくれているのです。(探すと、Visual Studioが自働で書き込んだプログラムも見れます。) 指し示すことを「参照」と言います。
    3. で、テキストボックス2も、同様に変数の名前に過ぎません。ちなみに、ご質問を拝読するに、テキストボックス2は最初、どのインスタンス(実体)も参照していないのではないかと思います。ちゃんと正しく代入文を書けば、上述の1.のインスタンス(実体)を参照できます。

    以上を踏まえると、

    「テキストボックス1=テキストボックス2」とすると、テキストボックス1も、テキストボックス2が参照してるTextBoxを参照するようになります。もし、テキストボックス2が何も参照していないのであれば、テキストボックス1も何も参照しなくなります。

    逆に、「テキストボックス2=テキストボックス1」とすれば、テキストボックス1が参照しているTextBoxを、テキストボクス2も参照するようになります。ご質問の流れからすると、この代入文を書いたあとで、「テキストボックス2.Text="文字列"」とすると、Form上のTextBoxに文字列が表示されるはずです。

    参考までに・・・、何も参照していないテキストボックス2のTextプロパティーに文字列を代入しようとすると、例外が発生すると思うのですが・・・・。


    (ホームページを再開しました)
    2011年10月5日 0:38
  • 外池さんがすでに書かれてますけど。

    > 予想では、Form上のテキストボックス(テキストボックス1)に"test"と表示されると思ったら
    > 表示されません。

    作成手順が書かれた通りでしたら以下のコートになりますが、表示されるのが正しいので予想はあってますよ。

    private TextBox テキストボックス2;

    private void button1_Click(object sender, EventArgs e)
    {
        テキストボックス2 = テキストボックス1;
        テキストボックス2.Text = "test";
    }


    > 基本的なことなのかもしれませんが、予想通りにいかない原因を教えてください。

    実際のコードが、書かれた文章通りじゃないのかなと思いました。
    もしかして、フォームを自分で new されてたりします?

    2011年10月5日 1:37
  • 外池です。

    まめぞうさんの最初のご質問の代入は、

    テキストボックス1(インスタンスを参照している) <=テキストボックス2(nullなのでは?)

    となっているし、そのあと、テキストボックス2.Textへ文字列を代入しているし、やはり表示は出ないのではないかと。


    (ホームページを再開しました)
    2011年10月5日 3:11
  • あ、そうですね。ごめんなさい。

    ご質問の際に
    テキストボックス1 = テキストボックス2
    と書かれてますけど、本当は
    テキストボックス2 = テキストボックス1
    が正しいですよ、という話ですね。
    (書かれた通りだとエラーが発生するはず、というのはおいといて)

    もしくは、C# の「=」は、数学の「等しい」じゃなくて「代入」です、という話かな。
    (追記:代入って書かれてるので違いますね)

    追記:すでに両者とも指摘されていて、いつもながら自分の読解力のなさにがっかり。。というか恥ずかしい・・・

    • 編集済み TH01 2011年10月5日 4:36 追記
    2011年10月5日 4:04
  • すいません。説明だけでなく、実際のコードも載せないと皆さんを混乱させてしまいますね。

    今後はコードも載せて質問したいと思います。

    で、今回の実際のコードを以下に記載します。

    テキストボックス1 はデザイナで直接貼り付けてます。

    テキストボックス2は、以下です。

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

            TextBox テキストボックス2 = new TextBox();

            private void button1_Click(object sender, EventArgs e)
            {

                テキストボックス1 = テキストボックス2;
                テキストボックス2.Text = "test";

            }
        }

    以上です。ご迷惑おかけしました。

    2011年10月5日 23:27
  • 外池です。なるほどです。

    テキストボックス2にも、ひとつ、TextBoxのインスタンスを代入していたんですね。ただ、このインスタンスは、確かに「実体」はあるのですが、Form1の上にちゃんと載っていません。幽体離脱状態、みたいな感じですね。

    まとめますと、

    デザイナでForm1に載せたTextBoxと、幽体離脱しているTextBoxと2つインスタンスがあります。

    button1_Clickイベントにおいて、まず、テキストボックス1とテキストボックス2のどちらの変数も幽体離脱しているTextBoxを指し示すようになって、そして、幽体離脱しているTextBoxのTextに"test"を書き込んだ

    ってことで、表示が現われないままなわけです。

    TextBoxをしっかりForm1に載せるために必要な操作は、InitializeComponent()の中を覗いてみると、書かれていますので参考になると思います。


    (ホームページを再開しました)
    2011年10月6日 1:10
  •     public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            TextBox テキストボックス2 = new TextBox();

            private void button1_Click(object sender, EventArgs e)
            {

                テキストボックス1 = テキストボックス2;
                テキストボックス2.Text = "test";

            }
        }

    CreateControl も Parent も設定してないため テキストボックス2 が表示されてないのだと思います。以下ざっと書いたもので、あまり検証していませんが、参考までにどうぞ。

    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }
    
        TextBox textBox2 = new TextBox();
    
        private void button1_Click(object sender, EventArgs e) {
    
            textBox2.CreateControl();
    
            textBox2.Parent = textBox1.Parent;
            textBox2.Location = textBox1.Location;
            textBox2.Size = textBox1.Size;
            textBox1.Hide();
            textBox1 = textBox2;
            textBox2.Text = "test";
        }
    }
    

    でもこんな面倒なことする必要が感じられません。コントロールを入れ替えるより、textBox1.Text の参照先を変えてやるだけでいいのではないでしょうか?


    ひらぽん http://d.hatena.ne.jp/hilapon/
    2011年10月6日 1:14
    モデレータ