C# 配置とアンカーについて

Mステ最高でした……タケル殿……マコト兄ちゃん……

さて、C#のフォームアプリケーションについて。
まずはこのサンプルを。


サンプル1

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace myapp
{
public partial class Form1 : Form
{
//ラベルオブジェクトを生成
private System.Windows.Forms.Label labelTL;
private System.Windows.Forms.Label labelTR;
private System.Windows.Forms.Label labelBL;
private System.Windows.Forms.Label labelBR;
private System.Windows.Forms.Label labelN;

//コンストラクタ
public Form1(){
//フォームおよびフォームに配置されるコンポーネントを初期化
//InitializeComponent();

//ラベルをインスタンス化
this.labelTL = new System.Windows.Forms.Label();
this.labelTR = new System.Windows.Forms.Label();
this.labelBL = new System.Windows.Forms.Label();
this.labelBR = new System.Windows.Forms.Label();
this.labelN = new System.Windows.Forms.Label();

//ラベルの設定
//わかりやすいように枠線も表示
this.labelTL.Text = ("左上");
this.labelTL.Location = new Point(0,0);
this.labelTL.BorderStyle = BorderStyle.FixedSingle;
this.labelTR.Text = ("右上");
this.labelTR.Location = new Point(200,0);
this.labelTR.BorderStyle = BorderStyle.FixedSingle;
this.labelBL.Text = ("左下");
this.labelBL.Location = new Point(0,200);
this.labelBL.BorderStyle = BorderStyle.FixedSingle;
this.labelBR.Text = ("右下");
this.labelBR.Location = new Point(200,200);
this.labelBR.BorderStyle = BorderStyle.FixedSingle;
this.labelN.Text = ("なし");
this.labelN.Location = new Point(100,100);
this.labelN.BorderStyle = BorderStyle.FixedSingle;

//ラベルをフォームのコントロールに追加
this.Controls.Add(this.labelTL);
this.Controls.Add(this.labelTR);
this.Controls.Add(this.labelBL);
this.Controls.Add(this.labelBR);
this.Controls.Add(this.labelN);
}
static void Main() {
Application.Run(new Form1());
}
}
}


実行結果



ラベルが5つフォームに追加されています。

しかしこのフォーム、このようにマウスで縁をドラッグしてサイズを変えると、





ラベルが隠れてしまいます。


そこでこちら。

サンプルコード2

Form2,cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace myapp
{
public partial class Form2 : Form
{
//ラベルオブジェクトを生成
private System.Windows.Forms.Label labelTL;
private System.Windows.Forms.Label labelTR;
private System.Windows.Forms.Label labelBL;
private System.Windows.Forms.Label labelBR;
private System.Windows.Forms.Label labelN;

//コンストラクタ
public Form2(){
//フォームおよびフォームに配置されるコンポーネントを初期化
//InitializeComponent();

//ラベルをインスタンス化
this.labelTL = new System.Windows.Forms.Label();
this.labelTR = new System.Windows.Forms.Label();
this.labelBL = new System.Windows.Forms.Label();
this.labelBR = new System.Windows.Forms.Label();
this.labelN = new System.Windows.Forms.Label();

//ラベルを設定
//わかりやすいように周囲の枠線を表示
//Anchorも設定するとユーザがフォームのサイズを変更しても追随するようになる
this.labelTL.Text = ("左上");
this.labelTL.Location = new Point(0,0);
this.labelTL.BorderStyle = BorderStyle.FixedSingle;
this.labelTL.Anchor = (AnchorStyles.Top | AnchorStyles.Left);
this.labelTR.Text = ("右上");
this.labelTR.Location = new Point(200,0);
this.labelTR.BorderStyle = BorderStyle.FixedSingle;
this.labelTR.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
this.labelBL.Text = ("左下");
this.labelBL.Location = new Point(0,200);
this.labelBL.BorderStyle = BorderStyle.FixedSingle;
this.labelBL.Anchor = (AnchorStyles.Bottom | AnchorStyles.Left);
this.labelBR.Text = ("右下");
this.labelBR.Location = new Point(200,200);
this.labelBR.BorderStyle = BorderStyle.FixedSingle;
this.labelBR.Anchor = (AnchorStyles.Bottom | AnchorStyles.Right);
this.labelN.Text = ("なし");
this.labelN.Location = new Point(100,100);
this.labelN.BorderStyle = BorderStyle.FixedSingle;
this.labelN.Anchor = (AnchorStyles.None);

//ラベルをフォームのコントロールに追加
this.Controls.Add(this.labelTL);
this.Controls.Add(this.labelTR);
this.Controls.Add(this.labelBL);
this.Controls.Add(this.labelBR);
this.Controls.Add(this.labelN);
}
static void Main() {
Application.Run(new Form2());
}
}
}



実行結果

初期画面はかわりませんが、マウスでドラッグすると、





このように、フォームの端っこにそれぞれくっついて移動してくれるようになります。
これでフォームの大きさが変更されてもラベルが隠れなくてすみます。

Anchor


コントロールクラスのプロパティです。コントロールが入ってる(バインドされてる)コンテナー(パネルとかフォームとか)の端にどのようにくっついていくかを決定します。
引数と戻り値はAnchorStyles 列挙体です。
コントロールクラスのプロパティなので大抵のクラスは使えると思います。

コントロールをフォームの縁ぎりぎりまででっかくする、とか
いろいろ使えるので試してみてね。

参考:AnchorStyles 列挙体



それでは、今回はこの辺りで。

C# Visual studioがない状態でフォームアプリケーションを作ってみる。

明日のMステにゴーストとスペクターが出ると聞いて録画待ったなし



さて、やせ我慢かつ偏った認識な自覚はありますが、
私はVisual studioのデザインモードをあまり信用していないので、
手打ちでフォームやボタンを表示させたりイベントを追加させたりしてみたいと思います。

サンプルコード

using System; 
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace myapp
{
class MyForm
{
//Formを継承したForm1クラスを作成
public partial class Form1 : Form
{
//ボタンオブジェクトを生成
private System.Windows.Forms.Button button1;

//コンストラクタ
public Form1(){
//フォームおよびフォームに配置されるコンポーネントを初期化
//InitializeComponent();

//ボタンをインスタンス化
this.button1 = new System.Windows.Forms.Button();

//ボタンの初期設定
this.button1.Location = new Point(100,100);
this.button1.Name = "Button1";
this.button1.Text = "押すな!";

//ボタンにクリックイベントを追加
this.button1.Click += new System.EventHandler(this.button1_Click);

//ボタンをフォームのコントロールに追加
this.Controls.Add(this.button1);
}

//クリックされた時のイベント
private void button1_Click(object sender, EventArgs e)
{
this.button1.Text = "押すなよ";
this.button1.BackColor = Color.Red;
this.button1.ForeColor = Color.White;
this.BackColor = Color.DarkGray;
}
static void Main() {
Application.Run(new Form1());
}
}
}
}



実行結果



ボタンを押すと



怒られます。それだけです。


ひっかかったところとかポイントとか。


InitializeComponent();

ビルドエラーで「'InitializeComponent' は現在のコンテキスト内に存在しません。」といわれ、
んなわけねぇだろと打ち直すもエラーは消えず。
リンクを参考にコメントアウトしてビルドしたところ、無事コンパイルできました。

ただし、コメントアウト戻したらまたおかしくなった。なんなんだいったい。

参考:'InitializeComponent' は現在のコンテキスト内に存在しません。」の対処方法



Color構造体

Color.RedColor.BlackというのがColor構造体です。

オブジェクトの背景色や文字の色を表します。

この構造体とは別にColorsクラスというのも存在します。どこで使うんだろう。

そして、何が違うんだろう。単純に構造体とクラスの違いでいいんだろうか。

C#というか、.NETにはシステム定義色というのが存在していて、Color構造体のプロパティからアクセスすることができます。
RedとかBlackってのがそれです。

参考:VisualStudioカラーコード表

ここが探した中で一番見やすい見本サイトでした。



コンポーネントとコントロール

参考:Component クラス

Control クラス

この違いもふわっとしかわからない……。
継承関係からするに、
コンポーネントの中の一部をコントロールと呼ぶのだろうなとは思うのだけど。
UIとGUIの違いという認識でもいいのだろうか…。違う気がする。


Application.Run(new Form1());

これは、Form1をインスタンス化して動かす命令です。
フォームを動かす命令にはApplication.Run()とForm.Show()があります。
Application.Run()はメインメニューに、Show()はサブメニューに使うと認識しています。

以下でくわしく説明されています。

参考:Application.RunとForm.ShowDialogの違い
dobon.net/vb/dotnet/form/runvsshowdialog.html




いくつか謎は残りますが、とりあえずcsファイルのみでフォームを表示させることができました。

それでは、今回はこのあたりで。

C# ToString()による数値→文字列変換とToString()のオーバーロードの話

コード載せることが増えたからはてなへの移行を検討しようかしら。
こっちは日記代わりにしてもいいかも。

ついに3号ですね敵ですねネクロムですね!!



さて、C#のObjectクラス、すなわちたいていのクラスには、ToString()メソッドが用意されています。
これにより、数値などを文字列に変換することができます。

また、このToString()メソッドにはいくつかオーバーロードがあります。
これを使うと、いろいろな書式の文字列に変換することができます。

ToStringメソッドのオーバーロードは、こちらにくわしく記載されています。

見た方がわかりやすいのでサンプルコード。


using System;

namespace myapp
{
class ToStr
{
static void Main(){
int value1 = 193;
double value2 = 7538.315;

Console.WriteLine("[ "+ value1.ToString() + " ]");
Console.WriteLine(value1.ToString("C"));
Console.WriteLine(value1.ToString("D5"));
Console.WriteLine(value1.ToString("E"));
Console.WriteLine(value1.ToString("F4"));
Console.WriteLine(value1.ToString("N"));
Console.WriteLine(value1.ToString("X"));

Console.WriteLine("[ "+ value2.ToString() + " ]");
Console.WriteLine(value2.ToString("C"));
Console.WriteLine(value2.ToString("E"));
Console.WriteLine(value2.ToString("F4"));
Console.WriteLine(value2.ToString("N"));
}
}
}


実行結果




ToString()の括弧の中に「書式指定子」と呼ばれるアルファベットと、「精度指定子」と呼ばれる数字を並べて書式を指定します。



表示桁数をそろえたいときなんかに使います。
たとえば、配列の中に保存されたint型の日付データをきれいに表示するときに便利です。

サンプルコード。
某シリーズ番組の放送開始日と時間を保存したint配列から、西暦以外のデータを2桁に揃えて表示しています。
通し番号は3桁指定。

using System;

namespace myapp
{
class Date
{
static void Main(){
int[,] date = new int[17,5]{{2000,1,30,8,0},
{2001,1,28,8,0},
{2002,2,3,8,0},
{2003,1,26,8,0},
{2004,1,25,8,0},
{2005,1,30,8,0},
{2006,1,29,8,0},
{2007,1,28,8,0},
{2008,1,27,8,0},
{2009,1,25,8,0},
{2009,9,6,8,0},
{2010,9,5,8,0},
{2011,9,4,8,0},
{2012,9,2,8,0},
{2013,10,6,8,0},
{2014,10,5,8,0},
{2015,10,4,8,0},};
for(int i = 0; i < 17;i++){
Console.WriteLine((i + 1).ToString("D3") + ": "
+ date[i,0].ToString("D2") + "年"
+ date[i,1].ToString("D2") + "月"
+ date[i,2].ToString("D2") + "日 "
+ date[i,3].ToString("D2") + "時"
+ date[i,4].ToString("D2") + "分");
}
}
}
}


実行結果



日付とかお金とか、あと小数点以下を揃えたいときに使いましょう。

それでは、今回はこの辺りで。

文字列比較の話

C#楽しくなってきたぜ! と思っていたらJavaも同時進行でやることになってしまって混乱を極めてまいりました。

フォーゼ完走しました。最後2話がもう佳境すぎて……!
やはりヒロインは歌星だったのか。


ネタはあれども書く時間がない。
一日30分くらいはまとめの時間に充てようかしら。

さて、タイトル通り、文字列比較についてです。
あらゆるプログラム言語がありますが、やはりどの言語でも文字列を扱うことは多いもの。

文字列を処理する命令はたくさんありますが、その中でも文字列比較、すなわち、文字列Aと文字列Bが同じかどうか判定する命令についてまとめます。



Java

strA.equals(atrB)


参照型(クラス)のStringオブジェクトで文字列を表現しています。
戻り値はbooleanです。

サンプルコード


class test {
public static void main(String[] args) {
String strA1 = new String("AAA");
String strA2 = new String("AAA");
String strB = new String("BBB");
System.out.println(strA1.equals(strA2));
System.out.println(strA1.equals(strB));
}
}


実行結果は

true
false

になります。



C#

strA == strB


参照型(クラス)のStringオブジェクトで文字列を表現しています。

if文の条件式のように直感的に比較ができるのでわかりやすいです。


C

#include〈string.h〉
strcmp(strA,strB)


char型の配列char[]で文字列を表現しています。
戻り値は、一致しているとき0が返り、それ以外は正か負のint型が返ります。
正負は文字コードの引き算の結果を示しています。



C++

strA == strB


参照型(クラス)のStringオブジェクトで文字列を表現しています。
C++は上で説明したCの特徴を受け継いでいますので、char[]型として文字列を扱うこともできます。

こちらもC#動揺直感的に比較ができます。



以上、文字列処理のうち、比較について軽くまとめてみました。

C#とJavaとC++、短い期間に次々習ったからごっちゃになってしまって……。

リファレンス見ながら頑張っていきたいです。



それでは、今日はこの辺りで。

続きを読む

C#の話 .NET freamworkとメモ帳とコマンドプロンプトでプログラミング

フォーゼ、残すところあと10話

前回、前々回とちょっと言ってましたが、最近C#触ってます。
ので、家でもC#使えるようにしてみました。

といっても、VisualStudio入れるのめんどくさい、もとい、HDDに空きがない。

なので今回は、だいたいのWindowsに標準で搭載されているであろうメモ帳とコマンドプロンプトでお手軽プログラミングしてみたいと思います。

今回参考にしたのはこちら。

初心者のためのC#プログラミング入門



C#とは?

Microsoft社が提供するプログラム言語です。
オブジェクト指向言語と呼ばれるもので、クラスを作ることができます。
Javaに似てますが違う部分もあります。
そんな認識です。



では、こちらのページに沿ってまずはプログラミングのための環境を整えていきます。

ちなみに、OSはWindows7です。


まず、.NET frameworkが入ってるかどうか確認します。

ひとによると思いますが、たいていC→Windows→Microsoft.NET→Framework64あたりにあります。
私のPCは64bitなので64があるか確認します。
もうひとつ中に入ると、このようにいくつかのバージョンが並んでます。



一番新しい「v4.0.30319」を選択します。

※人によって最新版は違うかと思われます。

その中に入ると、ずらーっといろんなファイルが並んでいます。
こいつらが、プログラムをコンパイルする手助けをしてくれるわけです。

続いて、パスを通す作業をします。
パスを通しておくと、あとで作業するときいちいちフルパスを打ち込まなくてもよくなります。
やらなくてもいいけどやるとすごい楽です。

まず、コントロールパネルの「システム」から「設定の変更」をクリックしてください。




続いて、「詳細設定」タブ下方の「環境変数」をクリック。




続いて出てくるウィンドウの「ユーザ環境変数」の「Path」を選択(大文字小文字の区別なし)し、編集をクリック(ない場合は新規作成)。




Pathの設定画面が出るので、編集の場合は前にあったものを消さずに、末尾に先程のバージョンファイルのパスを入力してください。



当方の環境であれば

;C:\Windows\Microsoft.NET\Framework64\v4.0.30319


このとき忘れてはいけないのが、パスの前の「 」(半角スペース)「;」(半角セミコロン)です。
セミコロンをつけることによって、違うディレクトリですよってのを示しています。

パスが通ったか確認してみましょう。
スタートメニューからコマンドプロンプトを起動します。

「csc」と半角で入力してEnter押してみましょう。
こいつがC#のコンパイラです。



こんなメッセージが出ればパスはうまく通っています。

「'csc'は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません

みたいなことを言われたら、パス通し失敗してますのでもう一度環境変数の設定を確認しましょう。

ちなみに、設定変更したらコマンドプロンプトを開き直さないと設定が反映されません
これで30分程ロスしたぞちくしょう。


さて、パスが通りましたらいよいよプログラミングです。

とても簡単なあれから行きましょう。

こんなプログラムを作りました。


using System;

namespace myapp
{
class Sample
{
public static void Main(string[] args)
{
Console.WriteLine("Hello! I'm Mokichi.");
}
}
}


メモ帳で作りましたが、なんでもいいです。
保存場所はCの中のcsというフォルダです。
コードはUniCodeにしました。好きなので。

ファイルの名前はhello.cs
この後ろにcsがついているファイルはC#のファイルということになります。
先頭は大文字にすべきだったな。

では、コンパイルしましょう。

コマンドプロンプトを起動し、さきほどのcsフォルダに移動します。
移動できたら以下のコマンドを実行しコンパイルを行います。

csc hello.cs


こんな画面が出ればコンパイル成功です。



csフォルダを確認すると、hello.exeというファイルが出現しています。
これが、実行可能ファイルです。
コマンドプロンプトから実行してみます。

hello.exe




やったぜ!


というわけで、おうちでC#ができるようになりました。

それでは、今日はこの辺りで。