C# は「とっかかり」は面倒。わかってみれば簡単 ・・・ 12/28 土
C# を使い始めました。「ひな形」は用意されているので、真っ白な画面をひとつだけ出すのであれば、すぐにできます。問題はその後で、「じゃあ、こういうことをやろうと思うんだけど、それって、どこに書けばいいの?」という状態になります。
どうやら、C++ と C# では、モノの考え方が違っているようです。どちらも、基本的には「人間が何かをしたら、コンピュータがそれに対応して何かをする」という形になっています。たとえば、人間がメニューをクリックしたら何かを表示する、とか、画面上でマウスを動かしたら、それに対応して図形が動く、とかです。このこと自体は、C++ も C# も変わりありません(こういうのを、イベント・ドリブンと言うのだそうです)。
問題は、それをどのように実現するかです。C++ の場合には、外から見た動きは、イベント・ドリブンですが、中身はそれよりも昔の考えをまだ引きずっていて、「これをやったら、次にこれをやる。その次にこれをやる。ここまで来たら、ここで待機する」みたいな手続きの順番がなんとなく見えています。
ところが、C# になると、イベント・ドリブンの考え方がさらに進んで、「こういうことを人間がやったら、こうする」という断片的なことを、バラバラっと書いておしまいです。「あとは、コンピュータが適当に動くから、なんとかなるよ」みたいな感じです。
「なんとかなるよ」と言われても、本当にちゃんと動くのかすごく心配です。したがって、できれば最初から順番に確認していきたいのですが、それができません。一応、順番に確認する手順も残っているのですが、プログラムの最初から順番に確かめていくと、比較的短い手続きのあとで、「ここから先は、おまかせ~」という状態になってしまいます。
「いやいや、おまかせでは困る。これとこれと準備しておきたいんだけどなあ」と考えて、仕方がないので、それなりのところに準備のプログラムを書いてみると、その準備をすっ飛ばしてしまうという状態で、ほとほと困ってしまいました。なにしろ、一番簡単と思われるプログラムが書けないのです。
結局2日ぐらいインターネットの資料をあちこち見て、試しては失敗し、試しては失敗しを繰り返した後、もうこれは自分ではどうにもならないと考えて、他の方に質問してみました。
質問してみたら、「これは、作法が違いますよ」という御指摘をいただき、「すいません。分かってませんでした」とお詫び申し上げ、すったもんだして、ようやくプログラムを作成することができました。記念すべき(?)最初のプログラムですので、ソースコードを書いておきます。
// // 次のようなことを実現した。 // // Form を表示させる。 // ラベルに現在の Form の左上の座標を表示させる。 // Form を移動させると、ラベルの座標の値も変化する。 // Form 内にボタンを表示させる。 // ボタンを押すと、ボタンの名前と、Form 全体の名前を変更し、Form を 左上に移動させる。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace test01 { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.label1 = new System.Windows.Forms.Label(); this.label1.AutoSize = true; this.label1.Text = "★★ TEXT ★★"; this.label1.Location = new System.Drawing.Point(50, 50); this.label1.TabIndex = 0; this.Controls.Add(this.label1); this.LocationChanged += Form1_LocationChanged; // 常に今の値が欲しい場合 this.button1 = new System.Windows.Forms.Button(); this.Controls.Add(this.button1); this.button1.Location = new System.Drawing.Point(50, 100); this.button1.Text = "my button 1"; this.button1.AutoSize = true; this.button1.Click += new EventHandler(button1_Click); this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove); } private void Form1_MouseMove(object sender, EventArgs e) { System.Drawing.Point sp = System.Windows.Forms.Cursor.Position; System.Drawing.Point cp = this.PointToClient(sp); int mx = cp.X; int my = cp.Y; this.Text = "Moved to (" + mx.ToString("0") + "," + my.ToString("0") + ")"; } private void button1_Click(object sender,EventArgs e) { this.Text = "Button1 Clicked"; this.button1.Text = "OK"; this.Left = 10; this.Top = 10; } private void Form1_LocationChanged(object sender, EventArgs e) { int xxx = this.Location.X; int yyy = this.Location.Y; string x1 = xxx.ToString("0"); string y1 = yyy.ToString("0"); this.label1.Text = x1 + "," + y1; } private System.Windows.Forms.Label label1; private System.Windows.Forms.Button button1; } }
一番のポイントは、「this.Controls.Add(this.label1)」という部分です。これが抜けていたのが最大の原因でした。また、ここには「this」が2回出てきますが、この「this」の意味が分かってくると、「なるほどなあ」と納得できるようになりました。
わかってみれば、いろいろなことがどんどんできるようになるのは、プログラミングも数学も一緒です。さっそく、次の課題に取り掛かろうと思います。