C# Event メモ

一般的にイベントハンドラーというのはイベント発生を待ち受けるイベントループに対して実際の処理の部分のこと。

EventHandler型というのは定義済みのデリゲート型のこと。EventHandler型の1つめの引数はObject型で2つめの引数がEventArgs型となる。

呼び出しは自身のクラスからのみ可能で、直接デリゲート型を公開せずに外部から登録/解除できる仕組み。

 

C# IEnumerable/IEnumerator メモ

C#2.0からイテレータ構文が導入され簡単に実装できるようなった。

戻り値は、IEnumerableを返す必要がある。

yield returnは処理を継続、yield breakはそこで処理が終了する。

 

C# 例外メモ

Try句の中では階層が深いところの例外でもキャッチできる。

Try句自体が階層になっている場合は上位に通知されない。

上位に通知する場合はCatch句の中でThrowする。

メッセージを持って上位に通知することもできる。①、②と表示される。

 

C# Delegate メモ

基本

複数代入できる(マルチキャスト)

匿名関数(匿名メソッド・ラムダ式)

C#2.0から匿名メソッド、C#3.0ラムダ式

C#2.0でジェネリック(型パラーメータ)が導入。Action,Func(返値有)を使うとDelegateの定義も不要になる。Action,Func等を定義済みデリゲートと呼ぶ。

実用性はないけど、ラムダ式と定義済みデリゲートで即時実行もできる。

C# フォルダ監視(ファイル追加・更新チェック)

簡易的なフォルダの監視ソフトを作ってみた。削除は検知せず、更新(ファイルサイズ)と追加のみ。

拠点間でのファイルの提出をシステム化しようとなり、先ず全てプログラム化かなとも考えたのだが、現状、ファイルの雛形の整理ができていないので、項目全てをプログラムに落とし込むには時間がかかってしまう。

それなら、ファイルそのものをフォルダに入れておけばいいだろうと考え監視ソフトを作ってみた。もっと高機能なソフトがフリーでもあるけど、自作しておくと後々ファイルの名称などでフィルタをかけたり自由にできる。

C# FFmpegにコマンド投げる③

以前も同じものを作ったのだけれど、もっと簡単に。

C# FFmpegにコマンド投げる①

C# FFmpegにコマンド投げる②

 

C# ガントチャート試作

C# DataGridView セルの結合

前回の記事でDataGridViewの結合を色々試しており、その流れで当初、進捗をセルの塗りつぶしで表現する感じのスケジュール管理用のソフトを作ろうかと考えていた。

作業の途中でふとセルの塗りつぶしではなくコントロールのLabelを置いたらどうだろうと思いついて、少し作業を進めてみた。

***

中小の製造業で工程表・計画表ってなるとだいたいガントチャートに類するもので管理するのが定番で、PERTのようなものが出てくることは少ない。
さらに製品マスタ(BOM)も整っていないことが多く、生産計画も手動計算か良くても半自動程度という場合が多い。

生産計画については、内示もなく多品種少量を短納期で作っているので、そもそも計画なんてできないという理由もある。

製品マスタ(BOM)がなく、短納期対応で頻繁に調整が必要な工程表・計画表なら、わざわざ専用ソフトではなくてエクセル+VBAの方が楽ということもあるようで、実際、VBAで魔改造した工程表が便利で乗り換えられないという話もあった。

C# DataGridView セルの結合

今回は標準ヘッダーを利用せず1行目2行目をヘッダーとして利用しており、試しに1行目の1列目2列目を擬似的結合してみた。

どこのサイトもだいたい同じ説明をしていて、CellPainting()で処理するのが基本という感じ。ちょっとつまづいたのが標準描画(セルの背景色とか文字列とか)で疑似的結合のRetangleが隠れてしまう現象で、回避するためにはe.Handled = trueで標準描画をキャンセルする必要があった。

例えば今回は利用しないけど、標準描画の一部をキャンセルする場合、e.Paint()で標準描画を呼び、e.Handled = trueで終了させる。
var p = e.PaintParts & ~DataGridViewPaintParts.Border;
e.Paint(e.ClipBounds, p);
e.Handled = true;
これでBorderの描画がキャンセルされる。

***

次は擬似的結合の範囲をループで動的に取得してみた。1行目1~5列目までは罫線Bottomを消すだけで、それ以降の1行目6列目以降(年月の部分)を疑似的結合している。

描画セル(1行目6列目)が画面から消えない(見えなくなることがない)作りならこれで問題ないのだけど、横スクロールなどで描画セルが画面から消えると疑似的結合のRectangleも消えて黒塗りになってしまうという厄介な問題が発生する。

スクロールの状態から描画セルを修正するような計算をすれば回避できるかもしれないけど、かなり面倒だしCellPainting()は頻繁に呼ばれているので、あまり複雑な計算もしたくない。

***

ちなみに、CellPainting()ではなくPaint()で処理することもできる。イベント引数からCellBoundsを取れないので、直接DataGridViewで指定するだけ。

***

色々考えたけど、結局、Rectangleの擬似的結合は止めて、CellPainting()では罫線だけ処理した。Alignmentで中央にできないし長い文字列も設定できないが、描画落ちするよりはいいかなという感じ。

***

数日後追記。

しばらく経ってから思いついたのが画像を利用するアイデアで、疑似的結合のサイズで動的に画像を生成して、それぞれのセルのサイズで抜き出して描画するという方法。

これだと見た目は結合されているけど、描画はセルごとなので黒塗りになってしまう問題も発生しない。

ただこの方法の場合、疑似的結合の範囲やサイズが固定なら問題ないけど、範囲やサイズが動的に変化するような仕様だとかなり複雑になってしまう。

 

C# DataGridView 操作基本

最近DataGridViewを扱う場合の流れ。

・内容の表示はモデルクラスのインスタンスをリスト化してバインドする。
入力内容をパースしたりする場合は、インスタンスのプロパティで処理。表示のスタイルについてはDataGridViewのセルで処理。

内部で保持するデータ型はstring型が多い。手入力される値はパースで弾いたときに空白に戻したいと思うことが多い。少し前はバインドせずパースの処理を間に入れていた。

ここでは試しにテキストボックスのバインド処理だけ。

・カラムとDBスキーマはリフレクションで連動させ、一箇所で指定。DBのテーブル作成もコード化しておく。
(ここでは記載していない)

・検索ボックスがある場合のクエリもリフクションで作る。
(ここでは記載していない)

・値が変更された行は色を変える。

・更新のときはスクロール位置を戻す。新規のときは一番下へスクロール。

・行を追加するときは1行のみの表示に切り替える。
更新処理はフラグ用のカラムを見て判断。

・マスタ化しているカラムは、クリック時にフォームを表示させる。
(ここでは記載していない)

C# 簡易インクリメンタルサーチ②

・カラムの表示/非表示、サイズ、並び順は上記と同じようにテキストファイルで指定できるようにする。(ここでは記載していない)
ユーザー側で変更したいであろう部分はテキストファイルで処理できるように。

本来はもっとクラスに分散させているけど、今回は見やすいように1つのファイルに入れた。一部は流用しているので載っていない。

ここまで手動でやらなくても色々方法はあるのだろうけど、何だかんだ手作りで落ち着いた。

Javascript/C# 手作りカレンダー

一般的にカレンダーを自作する必要性はないと思うけど、作る必要がでてきたのでとりあえずメモ。

C#(DataGridView)版