Visual Studio 2019 C# によるプログラミング 覚え書き

最終更新  2024.06.27


◆◆ 環境整備 ◆◆


● テキストエディタの文字サイズ 背景

ツール --- オプション --- 環境 --- フォントおよび色

●「表示」→「ソリューションエクスプローラ」

●「表示」→「ツールボックス」

右端にツールボックスが開く
Form にドラッグする

◆◆ プロジェクトの作成 ◆◆


新しいプロジェクトの作成

プロジェクトの種類
言語 C#   プラットフォーム  Windows  デスクトップ

(a) Windows フォームアプリケーション(.NET Framework)
(b) Windows フォームアプリ
(c) WPF アプリケーション

の 3 種類がある
違いは以下のサイトで説明されている。
https://impsbl.hatenablog.jp/entry/WinFormsAndWPF-WhatIsDifference

(b)(c) はアプリを配布するときに .NET Core をインストールする必要が
あるらしい。Windows に標準で添付されているものを使うのであれば
(a) を選ぶ。ただし、.NET Framework の最終バージョンは 4.8 で
開発がストップしているらしい。

「プロジェクト名」で指定したフォルダを「場所」の下に
掘る


◆◆ プロジェクトのフォルダを移動したとき (未確認) ◆◆


ソリューションのフォルダ一式を移動してから
sln ファイルを読み込むと、エラーがでる。

「ファイル」→「ファイルを開く」で開くと良いらしいが
未確認である


◆◆ プログラムの構成 ◆◆


Form1.cs   フォームデザイナが開く
       コントロールの上でダブルクリックすると
       コードを編集するタブが開く

Form1.Designer.cs   コントロールのオブジェクト名の確認


◆◆ コントロールの配置 ◆◆


表示 --- ツールボックス

コントロールをドラッグする

ctrl-C   ctrl-V  で複製可能
  新しいオブジェクト名がつく(ex. Label1 を複製して Label2)


◆◆ 文字の表示 ◆◆


TextBox を使う(1 行、複数行兼用)

フォントサイズ、テキストの設定
  右クリック --- プロパティ(画鋲マークで固定)

複数行表示
  動作 --- Multiline --- True

表示内容の更新
string line = string.Format("{0}\n",count);

textBox1.Text = line;
textBox1.AppendText(line);

Format("  {a,b:c}  \n",var);

b と c は省略可

a   何番目の変数か
b   桁数
c   F2  実数 小数点以下 2 桁
    E2  指数形式 小数点以下 2 桁   E のとき桁数は無効
    X   16 進

◆◆ ラジオボタン ◆◆


要素数の増加



◆◆ ドラッグドロップの受け取り ◆◆


(1)
using System.IO;    を追加

(2)
InitializeComponent(); の直後に
EnableDragDrop(textBox1);

(3) 以下のメソッドを追加

        private void EnableDragDrop(Control control)
        {
            //ドラッグ&ドロップを受け付けられるようにする
            control.AllowDrop = true;
            //ドラッグが開始された時のイベント処理(マウスカーソルをドラッグ中のアイコンに変更)
            control.DragEnter += (s, e) =>
            {
                // ドラッグドロップ時にカーソルの形状を変更
                // e.Effect = DragDropEffects.All;
                //ファイルがドラッグされたとき、カーソルをドラッグ中のアイコンに変更し、そうでない場合は何もしない。
                e.Effect = (e.Data.GetDataPresent(DataFormats.FileDrop)) ? DragDropEffects.Copy : e.Effect = DragDropEffects.None;
            };

            //ドラッグ&ドロップが完了した時の処理(ファイル名を取得し、ファイルの中身をTextプロパティに代入)
            control.DragDrop += (s, e) =>
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop)) // ドロップされたものがファイルかどうか確認する。
                {
                    string[] paths = ((string[])e.Data.GetData(DataFormats.FileDrop));
                    // ここに、ドラッグ&ドロップ受付時の処理を記述する
                    for (int i = 0; i < paths.Length; i++)
                    {
                        string line = Path.GetFileName(paths[i]) + " が DragDrop されました。\r\n";
                        textBox1.AppendText(line);
                    }
                }
            };
        }

◆◆ コマンドライン引数の表示 ◆◆


(1) Program.cs の static void Main() を以下のように変更

        static void Main(string[] args)

            Application.Run(new Form1(args));

(2) Form1 に引数を追加

        public Form1(string[] args)

(3) InitializeComponent(); の直後に以下を記述

            int i, n;
            string line;
            n = args.Length;
            line = string.Format("コマンドライン引数の個数は {0} 個\r\n", n);
            textBox1.Text = line;
            for (i = 0; i < n; i++)
            {
                line = string.Format("{0} : {1}\r\n", i, args[i]);
                textBox1.AppendText(line);
            }

◆◆ プログラム開始時のアクティブコントロールの指定 ◆◆


Form1 のコンストラクタ

InitializeComplnent(); の直後に
this.ActiveControl = this.button1;


◆◆ Form の名前 ◆◆


this.Text = "名前";

◆◆ アプリの終了 ◆◆


Application.Exit();


◆◆ フォーマット付き出力 (printf 相当) ◆◆


    string line;
    line = string.Format("{0} {1}\n",x,y);

    {0} {1} は変数の順番

    {a,b:c} のとき
         a: 変数の順番
         b: 桁数
         c: F3  小数点以下 3 桁


◆◆ Win32 API ◆◆


using System.Runtime.InteropServices;

    public partial class Form1 : Form
    {
       private const int CF_ENHMETAFILE = 14;

        [DllImport("user32.dll")]
        private static extern bool OpenClipboard(IntPtr hWndNewOwner);
        [DllImport("user32.dll")]
        private static extern int IsClipboardFormatAvailable(int wFormat);
        [DllImport("user32.dll")]
        private static extern IntPtr GetClipboardData(int wFormat);
        [DllImport("user32.dll")]
        private static extern int CloseClipboard();

--------------------------------------

                    OpenClipboard(this.Handle);
                    IntPtr hmeta = GetClipboardData(CF_ENHMETAFILE);
                    Metafile emf2 = new System.Drawing.Imaging.Metafile(hmeta, true);
                    CloseClipboard();

                    line = string.Format("拡張メタファイル:幅 {0} 高さ {1}" + NL, emf2.Width, emf2.Height);
                    textBox1.AppendText(line);
                    pictureBox1.Image = emf2;


◆◆ PictureBox の使い方 ◆◆


pictureBox1.Image = img;
pictureBox1.Image = emf;


◆◆ --------- ここから下は 2014 の記事 -------------- ◆◆


◆◆ ファイル出力 ◆◆


CWD は project_name\bin\Debug の下

アスキー出力

    StreamWriter file = new StreamWriter(@"rgb.ppm");

    file.WriteLine("P6");
    file.Write(x);

    file.Close();

バイナリ出力

    FileStream fs = new FileStream(@"depth.pgm", FileMode.Create);
    BinaryWriter bw = new BinaryWriter(fs);

    string header = "P5\n640 480\n255\n";
    char[] array = header.ToCharArray();
    bw.Write(array);

    for (int i = 0; i < 480*640; i++)
    {
        byte pixel = (byte)(depthPixel[i] >> 8);
        bw.Write(pixel);
    }

    string trailer = "\n";
    char[] array2 = trailer.ToCharArray();
    bw.Write(array2);

    bw.Close();
    fs.Close();

◆◆ ファイル入力 ◆◆


    string   line, line2;
    string[] separator = {" "};

    StreamReader sr = new StreamReader("sample.txt");

    line = sr.ReadLine();
    list = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);

    x = int.Parse(list[0]);
    y = int.Parse(list[1]);

    line2 = String.Format("x = {0}   y = {1}\n",x,y);
    memo.AppendText(line);

    配列 list の要素数は list.Length で取得可能

◆◆ C++ と C# で異なる変数の型 ◆◆


C++ と名称は同じで内容が異なるものがある (char)

C                  C#
---------------------------
unsigned char      byte
char               sbyte

C# での char は 16bit unicode である。


◆◆ 値型と参照型 ◆◆


値型     byte sbyte int double char, 構造体
参照型   string, クラス

構造体が値型でクラスが参照型であることに注意!!
代入のとき違いが発生する。
string は参照型だが例外的な性質を持つため後述する

---- 参照型の落とし穴 ----

class Myclass
{
    public int x;
}

.......

MyClass a, b;
a = new MyClass();
b = new MyClass();

a.x = 1;
b.x = 2;
Console.WriteLine(b.x);  // 2 である

b = a;                   // b は a のアドレスを指す
Console.WriteLine(b.x);  // 1 である

a.x = 3;
Console.WriteLine(b.x);  // 3 である

このように、a への代入が b に及ぶ。

---- 比較演算子 ----

a = b のとき、参照型の場合はアドレスが比較される。
内容は比較しない。

上記のプログラムにおいて class Myclass を
struct Myclass に変更すると、Consolw.WriteLine の
結果は

2
1
1

となる。

◆◆ string について ◆◆


string は参照型だが、値型として扱ってよい。

a = b のとき b のアドレスを a に代入するのではなく、
右辺が新しいインスタンスとして自動生成され、
a に代入される。

比較演算子 a = b のとき、アドレスではなく
文字列の内容を比較する。


◆◆ 関数の引数 ◆◆


func(a, out b);

func(
{


}

値型の変数   値渡し
             out をつけると参照渡し


◆◆ 変数名の付け方 ◆◆


ハンガリアン表記    strName    先頭に型を明示する
パスカル            UserName


◆◆ 数値と文字の相互変換 ◆◆


int a;
string str;

str = a.ToString();
a = Convert.ToInt32(textbox1.Text);

Convert.ToInt32()
Convert.ToString()
Convert.ToDouble()


◆◆ コンソール出力 ◆◆


Console.Write();           改行なし
Console.WriteLine();       改行あり

コンソールアプリで終了前にキー入力を
要求するときは

Console.ReadLine();

あるいは Ctrl + F5