C# memo
Suns & Moon Laboratory
NAudio
プロジェクト→参照の追加→参照マネージャ→参照
に、NAudio.dllを登録する。
フィールド
静的フィールド
クラスに属すので、複数のインスタンスを生成しても、1個の格納場所が生成されるだけ。
インスタンスフィールド
インスタンスに属すので、複数のインスタンスを生成した場合、複数の格納場所が生成される。
https://msdn.microsoft.com/ja-jp/library/aa645751(v=vs.71).aspx
パブリックまたは保護されたインスタンス フィールドは提供しないでください。
https://msdn.microsoft.com/ja-jp/library/ms229057(v=vs.100).aspx
命名規則
public
Pascal形式 各単語の先頭を大文字にする。ObjectPascal
パラメータ
camel形式 先頭は小文字、以降単語先頭大文字。 objectPascal
ローカル変数(特に指定無いっぽいので個人的にはこうするかな...)
snake形式 単語をアンダーバーでつなぐ。 object_pascal
わかりやすい解説
某エンジニアのお仕事以外のメモ C#の命名規則
MS https://msdn.microsoft.com/ja-jp/library/ms229002%28v=vs.100%29.aspx
複数の単語で構成されるパブリック メンバー、型、および名前空間の名前には、常に Pascal 形式を使用してください。
例
ToStrring()
この規則は、インスタンス フィールドには適用されません。 「メンバーのデザインのガイドライン」に記載されている理由により、パブリック インスタンス フィールドは使用しないでください。
と書いてあるけど、理由わからなかった...orz
まぁ、基本的には非公開メンバだから決まって無くても良い気はする。
パラメーター名には Camel 形式を使用してください。
例
fileName
いわゆる閉じた形式の複合語の各単語は大文字にしないでください。 これらは、一語として記述される複合語 ("endpoint" など) です。
これは辞書で調べるしかない。
Generic
Genericを使うといろいろと便利
- コンパイル時型チェックが出来る
 - 型が決まっているので、実行時の型チェックが省略されて高速<らしい
 
 using System.Collections.Generic;
 List<T>
 Queue<T>
foreach
 foreach(KeyValuePair<string,string> kvp in value_dic)
 {
 	kvp.Key;
	kvp.Value;
 }
同期
 WaitAll(WaitHandle[])
列挙
 public enum eJudge
 {
 	TachiBlue = 0,
 	TachiRed,
 	TachiYellow
 }
abstractな関数
関数だけで無く、クラス宣言にもabstract必要
abstract public class AbsBaseClass
{
    abstract public void Func();
}
 public class MyClass : AbsBaseClass
{
    override public void Func()
    {
        Console.WriteLine("MyClass Hello!!");
    }
}
コンストラクタの継承
 using System;
 using System.Collections.Generic;
 using System.Text;
 namespace ConsoleApplication1
 {
     class Program
     {
         static void Main(string[] args)
         {
             Console.WriteLine("---- new IkBook()");
             IkBook book = new IkBook();
             Console.WriteLine("---- new IkBinder()");
             IkBook binder = new IkBinder();
             Console.WriteLine("---- new IkBook(string)");
             IkBook book2 = new IkBook("test");
             Console.WriteLine("---- new IkBinder(string)");
             IkBook binder2 = new IkBinder("test");
         }
     }
     class IkBook
     {
         public IkBook()
         {
             Console.WriteLine("IkBook()");
         }
         public IkBook(string prm):this()//★このthisでIkBook()呼び出し
         {
             Console.WriteLine("IkBook(string)");
         }
     }
     class IkBinder : IkBook
     {
         public IkBinder()
         {
             Console.WriteLine("IkBinder()");//引数無しは、暗黙にbaseのコンストラクタが呼ばれる
         }
         public IkBinder(string prm):base (prm)//★このbaseでIkBook(string)を呼び出し
         {
             Console.WriteLine("IkBinder(string)");
         }
     }
 }
実行結果
 ---- new IkBook()
 IkBook()
 ---- new IkBinder()
 IkBook()
 IkBinder()
 ---- new IkBook(string)
 IkBook()
 IkBook(string)
 ---- new IkBinder(string)
 IkBook()
 IkBook(string)
 IkBinder(string)
 続行するには何かキーを押してください . . .
インデクサ
プロパティを配列風アクセス
 using System;
 using System.Collections.Generic;
 using System.Text;
 namespace ConsoleApplication1
 {
     class Program
     {
         static void Main(string[] args)
         {
             Books books = new Books();
             Console.WriteLine("-------- before");
             Console.WriteLine(books[0]);
             Console.WriteLine(books[1]);
             Console.WriteLine(books[2]);
             books[1] = "デザインウェーブマガジン";
             Console.WriteLine("-------- after");
             Console.WriteLine(books[0]);
             Console.WriteLine(books[1]);
             Console.WriteLine(books[2]);
         }
     }
     class Books
     {
         List<string> Items = new List<string>();
         public Books()
         {
             Items.Add("トラ技");
             Items.Add("DWM");
             Items.Add("Interface");
         }
         public string this[int i]
         {
             set
             {
                 Items[i] = value;
             }
             get
             {
                 return Items[i];
             }
         }
     }
 }
ファイルの列挙
参考:@IT:.NET TIPS ファイルやディレクトリの一覧を取得するには? - C#
 using System.IO;//Directory
 namespace test_FindFirst
 {
     public partial class Form1 : Form
     {
         public Form1()
         {
             InitializeComponent();
         }
         private void button1_Click(object sender, EventArgs e)
         {
             EnumDirsFiles("D:\\testdata");
         }
         void EnumDirsFiles(string dir)
         {
             //ファイルの列挙
             string[] files = Directory.GetFiles(dir);
             foreach (string s in files)
             {
                 listBox1.Items.Add(s);
             }
             //ディレクトリの列挙
             string[] dirs = Directory.GetDirectories(dir);
             foreach (string s in dirs)
             {
                 EnumDirsFiles(s);//再帰呼び出し
             }
         }
     }
 }
日付時刻
DateTime dt = DateTime.Now;
System.Console.WriteLine(dt.ToString("yyyyMMddHHmmss"));
時間計測
System.Diagnostics.StopWatchを使う
参考:http://www.atmarkit.co.jp/fdotnet/dotnettips/412stopwatch/stopwatch.html
ネットワークドライブのプロジェクトでセキュリティ例外
ネットワークドライブ上のプロジェクトを開こうとすると、セキュリティ例外が発生します。
対処方法は、コンパネ→管理ツール→Microsoft.NET Framework 2.0構成→マイコンピュータ→ランタイムセキュリティポリシー→エンタープライズ→コードグループ→All_Code→このレベル以下のポリシーレベルは評価しないをチェック

画像描画いろいろ
なんかいろいろあってわかり辛いのでまとめ。
- 描画 Graphics
 - ファイルとかメモリとか Imageを継承したBitmapやMetafile
 
Image系
抽象化されていない画像形式。だと思う。
Image←Bitmap
Image←Metafile
Graphics系
抽象化された画像
Graphics GDI+描画サーフェイスをカプセル化
- Control.CreateGraphics()
 - Control.PaintイベントのPaintEventArgs引数で、Graphicsを取得可能
 - ImageからSystem.Drawing.Graphics.FromImage()で作成可能
 
Graphics.DrawImage()で、Imageを描画可能
配列の処理速度(Array,List)
- ArrayとListは、Listが2〜3倍くらい遅い
- Listは、(当然だが)メモリを喰う。
- Arrayは、確保した量だけメモリを喰う。
 - ArrayはResize時、要素の全てをコピーする
   
C#で__LINE__や__FILE__プリプロセッサマクロを使いたい
まさにこれ→http://messiah-annex.at.webry.info/200502/article_7.html
StackFrameを使うとは、なるほどねぇ。
C言語のmemcpyしたい
Array.CopyTo
ちゃんと型変換してくれちゃう...してくれなくても良いのにねぇ。
byte[] arr1 = new byte[] {0,1,2,3,4,5,6,7};
UInt32[] arr2 = new UInt32[8];
arr1.CopyTo(arr2,0);
for (int i = 0; i < arr2.Length; i++)
{
	System.Console.WriteLine(arr2[i].ToString());
}
Buffer.BlockCopy
これこれ、まさにmemcpy。でもヘルプの解説意味わからん。
引数は、バイトオフセットとかバイト数なので注意。
byte[] arr1 = new byte[] {0,1,2,3,4,5,6,7};
UInt32[] arr2 = new UInt32[8];
Buffer.BlockCopy(arr1, 0, arr2, 0, arr1.Length);
for (int i = 0; i < arr2.Length; i++)
{
	System.Console.WriteLine(arr2[i].ToString());
}
C言語のmemsetしたい
簡単な方法は無さそうです。
0初期化ならば、newすれば良いかと思われます。
int[] arr = new int[10];
arr = new int[10];
イベント
引数無し
    class TestClass
    {
        public event EventHandler Update;
        public void Test(){
                Update?.Invoke(this, EventArgs.Empty); // ?.Invokeでnullチェック省ける
        }
    }
//-----------------
    class Form1{
        TestClass test = new TestClass();
        public Form1(){
            test.Update += new EventHandler(event_update);
        }
        public void event_update(object sender, System.EventArgs e){
            //event処理
        }
    }
delegate
デリゲート
Formのイベントなんかの実装は、これ。だと思う。
using System;
namespace TestDeleGate
{
    public delegate void DelegateX(); //デリゲートの定義
    public class MyClass1
    {
        public DelegateX EventX;//デリゲートの変数宣言
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyClass1 obj1 = new MyClass1();
            obj1.EventX = event_x;//デリゲートに関数割り当て
            obj1.EventX(); //割り当てた関数呼び出し
        }
        static void event_x()
        {
            Console.WriteLine("デリゲート呼び出し");
        }
    }
}
描画
クラス
| PictureBox | Formに配置出来るコントロール | 
| Image | Bitmap,Metafileの抽象基本クラス | 
| Graphics | 描画操作はこのクラス(GDI+をカプセル化) | 
画像を描画するには、Graphicsを使う。Graphicsの作成方法。
Graphicsを作成する方法
- イベントの一部から取得。PaintEventArgs.Graphics
 - コントロールの、CreateGraphicsメソッドを使う
 - Imageから作成する。System.Drawing.Graphics.FromImage(System.Drawing.Image)
 
描画は、大きく二種類に分かれる
XXXには代表的(というか、自分が使いそうなのは)に、こんなのがある。
- Icon
 - Image
 - Line
 - Lines
 - Polygon
 - Rectangle
 
描画のスタイル指定に使うオブジェクト
Pen
端点の形 Pen.StartCap,Pen.EndCapをLineCapで指定する。
線の接合部の形 LineJoin
座標変換
Matrixを使うか、Graphicsの下記メソッドを使う。
- MultiplyTransform
 - ResetTransform
 - RotateTransform
 - ScaleTransform
 - TransformPoints
 - TranslateTransform
 
Matrix操作
- Multiply Matrixの乗算
 - Rotate 回転
 - RotateAt 指定した点を中心にした回転
 - Scale 縮尺
 - Shear 傾斜ベクタ?
 - Translate 平行移動
 
クリッピング
DLLを呼ぶ
VC#2010
DLLの文字列がPAnsiChar(LPCSTR)なら、stringで良いみたい。
http://www.s-m-l.org/dev/delphi.html#DLL
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [System.Runtime.InteropServices.DllImport("testdll1.dll")]
        private extern static void func1(string path, uint opt);
        private void button1_Click(object sender, EventArgs e)
        {
            func1(textBox1.Text, 1);
        }
    }
}
ボタンの画像を指定する
Imageプロパティに指定する。
コードで指定する時は、リソースから。
button2.Image = Properties.Resources.arrow_left_48;
http://www.atmarkit.co.jp/fdotnet/dotnettips/990winformbtnimage/winformbtnimage.html
リソースの追加方法
メニュー→プロジェクト→xxxxのプロパティ→リソース→既存のファイルの追加
で、
arrow_left.pngを追加するとarrow_leftで定義される。
これを使うのは、こんな感じ。
dataGridView1.Rows[idx].Cells[3].Value = Properties.Resources.arrow_left_64;
Form全体をフォントサイズでスケーリング
1.FormのAutoScaleModeをFontにする。
2.Fontをnewして割り当てる。(Font.Sizeは書き込み出来ない為)
        private void btnBig_Click(object sender, EventArgs e)
        {
            Font = new Font(Font.OriginalFontName, 30);
        }
        private void btnSmall_Click(object sender, EventArgs e)
        {
            Font = new Font(Font.OriginalFontName, 5);
        }
        private void btnNormal_Click(object sender, EventArgs e)
        {
            Font = new Font(Font.OriginalFontName, 9);
        }
Font.Sizeはdecimal型
128bit実数型
サフィックスにmを付けないと、double型になりエラーとなる。
decimal myMoney = 300.5m;
DataGridViewのFontや行高さの設定
フォント設定はちょっと違う場所にあったり、あちこち分散している。
ヘッダ
ColumnHeaderDefaultCellStyle.Font
RowHeaderDefaultCellStyle.Font
データ
DefaultCellStyle.Font
行高さ
RowTemplate.Height
TextBoxをメモ代わりに使う
とにかく遅いので、SendMessage推奨
https://www.ipentec.com/document/document.aspx?page=csharp-textbox-slowdown-in-the-text-additional
 using System;
 using System.Windows.Forms;
 using System.Runtime.InteropServices;//★
 namespace TestConvert
 {
     public partial class Form1 : Form
     {
         const int EM_REPLACESEL = 0x00C2;//★
         [DllImport("User32.dll")]//★
         public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);//★
         public void memo(string str)
         {
             SendMessage(textBox1.Handle, EM_REPLACESEL, 1, str + "\r\n");
         }
         public Form1()
         {
             InitializeComponent();
         }
         private void button1_Click(object sender, EventArgs e)
         {
             memo("abc");
         }
     }
 }
TMemoっぽく使う※遅い
textBox1.AppendText("abc" + Environment.NewLine);
だが、実用性無いレベルに遅いので
なるべく文字列を作っておいて、代入する方が良い
string str = "a" + + Environment.NewLine + "b";
textBox1.Text = str;
どちらにしろ遅い。
とにかくSendMessage使え
文字コード
改行
Environment.NewLine
タブ,CR,LF
"\t\r\n"
リモートデバッグ
2016-10-19
開発環境 VisualStudio 20015 C#
開発機 Windows7
リモート機 Windows10
リモートデバッグのツールをダウンロード。結構リンク切れで探した。あったと思ったら2013とか...
Remote Tools for Visual Studio 2015 Update 3
一番はまった所。
ファイルパスを、開発機とリモート機で同じにしないと動かないらしい。
SpaceKey Visual Studio 2015でデバッグ実行をWindowsタブレットで行う
プロジェクト→プロパティ→デバッグ→「リモートコンピュータを使用する」にチェック
コードの整形
ソースのコード整形
編集→詳細→ドキュメントのフォーマット
Ctrl+K,Ctrl+D
高DPIサポート
なんかよくわからんが表示がずれる。
例えば開発機が倍率100%で、実機が150%とかの場合。
App.config に下記追加だけで良くなった気がする。
vs2015
Win7
.NET4.5.2
  <appSettings>
    <add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
  </appSettings>
詳しくはここ
高DPIのサポート
バージョン
PropertiesのAssemblyInfo.csを修正する。
// アセンブリのバージョン情報は次の 4 つの値で構成されています:
//
//      メジャー バージョン
//      マイナー バージョン
//      ビルド番号
//      Revision
//
// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を
// 既定値にすることができます:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.15")]
[assembly: AssemblyFileVersion("1.0.0.15")]
これでファイルからバージョンとれる。
 System.Diagnostics.FileVersionInfo ver = System.Diagnostics.FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
 return "Version " + ver.ProductVersion;
文字列を大文字小文字区別せず比較する
string str1 = "abc";
string str2 = "ABC";
bool is_equal = str1.ToUpperInvariant() == str2.ToUpperInvariant();
http://dobon.net/vb/dotnet/string/stringequals.html#section4
DataGridViewのヘッダ文字列を中央寄せ
下記コード実行する。
dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
【C# DataGridView】列ヘッダーのテキストを中央揃えにする
2024-08-14 11:00:23 32400