Linuxを中心とした話題を投稿予定。 使用ディストリビューションであるFedoraが中心になると思われます。http://oedipa.wiki.fc2.com/にてTips Wikiを公開してます。
例外処理が甘いけど、一応解決
昨日の記事にて、メニュー項目とインスタンスをどうやって結びつけようかと思案していたのですが、1つの解決策を得ました。
どうもFormクラスをはじめとしたControl全般は、Tagというプロパティを持っており、そこにそのコントロールと関連性の高いオブジェクトを放り込むようです。Tagはobjectクラスとなっているため、なんでも保持できます。一般的には文字列を入れておき、イベント先でswitchなどを駆使して処理を行うらしいです(この考え方で合ってるのかな?)。
で、私はメニューリストのTagプロパティに、インスタンスの参照をそのまま放り込んでみました。イベントハンドラに登録されているメソッドでは、senderとなるオブジェクトを決め打ちとし、Form型にキャストして処理しています。本来、インスタンスの参照をあまり複数で管理すべきではないということは承知しているのですが・・・、こうしておくと初期化処理の部分でTagプロパティに参照を渡すだけでよく、楽なんですよねぇ・・・。
まぁ処理の都合上子フォームのTagプロパティには親フォームのメニューリストの参照を渡していたり。そうしないとメニューリストに項目を追加するたび、子フォームごとにイベント処理を書かなくてはいけないので邪魔くさいんですよね・・・。
まぁTagはおいといて、受け取ったイベントメソッド側でobjectクラスからFormクラスへキャストしているので、万が一イベントを送ってきたインスタンスがこちらの装丁しているクラスでなかったとしたらあっけなく例外を吐きます^^; まぁ自分で管理している以上そんな処理は有り得ないのですが・・・、お行儀がいいとはとても言えませんね(苦笑)
これに関しては、VC#のコードデザイナのイベントメソッド自動生成に任せているからobject型になっているのであって、これを自分でメソッド書いてイベントハンドラに追加してやれば好きに出来るはず・・・と思っていたり。ちょっとまだイベントハンドラについては理解し切れていない部分があるので間違ってるかも知れないけど、おそらくそれで解決できるはず。
Formクラス以外はそのイベントメソッドを利用することを想定してないから、メソッドの引数自体をそうしてしまえばコンパイルの時点で明らかにおかしいものは弾けるしね。
ということでお行儀のいいソースにするためにそこは修正予定。ただ、自動生成しちゃったイベント登録部分ってのはpartialで隠されてる部分だからあんまり手動で消したくないのよねぇ・・・。リファクタで消えたっけ・・・? それがネックだなぁ。
まぁ最悪手動で消すとして、これである程度保守性も確保できたかな。
こっから先はいよいよ実行処理のアルゴリズム実装かな。Timerによるサンプリングレート管理とデータのバインディング処理がネックになるかな・・・。とりあえずは実装モデルを考えないと!
スポンサーサイト



どうするのがスマートなのかなぁ・・・
とりあえずグラフを描画するWindows Formのサブクラスが完成。コンストラクタにしかタイトルや軸のラベル名を変更させる手段を持たせなかったけど、途中で変更することはまず内だろうしそれは別に問題ないかな。汎用性を持たせるならプロパティでも設定すべきなんだろうけど・・・、まぁいいかな。グラフを描画させたいデータソースによってタイトルと軸のラベルなんて決まるもんだし。それはインスタンスを生成する時点で決まってるでしょう、きっと。
とりあえずある程度の汎用性を持たせたグラフ描画フォームは完成と言っていいかな。データソースにはdouble型の配列を引数として受け取るようにはしましたが・・・、あれはどうにか抽象化できんかなぁ。ジェネリクスメソッドにしてもいいんだけれど、確実に型制限をつける必要が出てくるし。値型だけを引数としたいところだけれど、それってできたっけなぁ・・・? まぁよしんばそれができたとして、ArrayListクラスとかは受け取れないけどそれはどーすんだとか諸々の問題はありますが^^;
まぁそれはそこまで大きな問題ではないのですが、今気になっているのはMDIの扱い。描画フォームができたので、それをMDIの子フォームとして呼び出すランチャーを作っているのですが、これをもう少しスマートに書きたいんですよね。
とりあえず、メニューの”Results”をクリックすると、プルダウンメニューが現れ、MDIの子フォームであるいくつかのグラフ描画フォームを選ぶことでMDI領域にフォームが現れるという仕様にしています。この部分は問題なく実装できているのですが、実に泥臭い方法で実現してるんですよね・・・。
それぞれのメニューの項目のクリックイベントのハンドラとしてそれぞれのウィンドウの表示メソッドを書いて居るんです。
が、基本的にやることはみんな同じ。対象となるフォームインスタンスが違うだけ。なので、メニュー内容とそのウィンドウをなんとかリンクさせることが出来れば、同じイベントハンドラで実現できるはず、と思ってはいるのですが・・・、その方法が思い付かないんですよねぇ。
親フォームがロードされた時点で全子フォームのインスタンスは生成されているので、メニューのクラスに関連づけさせるようなプロパティでもあればいいんですが・・・、ない気がしますしねぇ^^;
ってなると自分で実装・・・はしんどいよなぁ^^; けど毎回毎回子フォームを追加してメニューに追加したときに同じようなコードを書かなくちゃ行けないのは明らかに保守性が悪いし・・・。
どうにかしたらできるはず。ってなわけで当面はここをどうにかする方法を考えつつ、プログラムの実行部分を作っていきましょうかね。別スレッドで回すのはいいんだけれど、内部で使われている値を読み出すときはどうやって読み出そうかなぁ・・・。原則、リードオンリーだからロックを掛ける必要はないと思ってはいるのだけれど・・・、WAVファイルからサンプリングレートを取得してそのレートで実行するようなプログラムを書きたいな。そうすれば実際に処理にどれだけ時間が掛かったかが把握できるし。
できたら処理実行クラスはGUIとは完全に切り離して、単体でも動作するような形にしたいからなぁ。あくまでGUI部分はただのランチャってのが理想。アルゴリズムの実装はさして難しくはないけれど、GUIとの連携部分をどうするか、やなぁ・・・。
このあたり、今までまともに組んだことがないからちょいときついなぁ。さて、またネットとかで情報集めて頑張りますかねぇ^^