ラベル C# の投稿を表示しています。 すべての投稿を表示
ラベル C# の投稿を表示しています。 すべての投稿を表示

5/30/2010

SilverlightにおけるCustom Template Controlの作り方について

どうもJudaです。
今回はSilverlightにおけるカスタムテンプレートコントロールの説明です。
コントロールのカスタムテンプレートとユーザーコントロール継承の違いですが、私見では、
  1. カスタムテンプレートは、再利用可能なユーザーコントロールの開発
  2. ユーザーコントロール継承は、再利用を含めないユーザーコントロールの開発
であり、後者のユーザーコントロール継承は、特定の部位に別のコントロールを埋め込んだりと言うことを基本的に考えていない場合だと思います。もちろん様々な方法が考えられますが、構造を変えたりはできないので、基本的には作成した際の構造を逸脱することは出来ず、またユーザーコントロールの構造を残したままの改造なので、DependencyPropertyの数が増えすぎる傾向にあります。
今回はCustomTemplateControlの話なのですが、こちらの開発に関しては、注意することは主には二つ。
  1. TemplatePartAttributeなどのパラメータは今度の実装者がどういうパラメータをUIとして定義しているのかを知るための補助的な情報であること。メタデータとして定義されるので、当たり前ですが。
  2. GetTemplateChildというメソッドを使って、自身で定義したフィールド変数にそのコントロールへの参照を設定します。これをしないと煩雑な呼び出しがいっぱいなMFCみたいなことになるので、注意です。
呼び出しのタイミングですが、MSDNのベストプラクティスによれば、OnApplyTemplateのオーバーライドのタイミングが最速になるようです。またイベントの定義の問題などもありますので、変数を直に触らせるのではなく、いくつかのレイヤーをかませて抽象化して、エラーを発生させない機構を作る必要がありますが、あくまで再利用を考えれば、ベストプラクティスに乗っとる必要性がありますが、自己で管理しているレベルでの開発ならば、そこまで神経質になる必要性はなさそうです。
テンプレートコントロールの呼び出しタイミングですが、コンストラクタ→Load→OnApplyTempleteになるので、カスタムユーザーコントロールからの移植の場合には注意が必要になります。

またGeneric.xamlに記述されるので、Blendではすこぶる開発しにくいと思います。また基本的にクラスの定義部分が大きくなりすぎる感がありますので、可能であれば、Partial Classの利用をおすすめします。

5/06/2010

ADO.NET Data Serviceについて

どうもJudaです。

ADO.NET Data Servicesについてですが、主キーでNot NullableなAutoIncrimentなカラムの値の設定方法ですが、どうも値を自動で上書きされるようです。

それ以上に注意しないといけないのは、Entity FrameworkのEntity Data Modelで接続部分をになってくれる構造体群に対しては、接続元になっているDBの各列の型、既定値、Null許容かなどの、「SQL Expressでつくったから、Wizardがやってくれている」と幻想をいだいているものは大半がダメです。そげぶされます。

明示的に設定するようにMSDNでも書いてあります。調べないとわからないのですけど、ちょっとはどこかに書いて欲しいものであります。

また失敗した場合のエラーログが欲しい場合は、Wizardが書いてくれているコードに対して、いくつかの属性を設定すればより詳しいエラーメッセージを得られるのですが、前に書いたのを忘れたので、探しています。属性についても本当に調べにくい。そのくせ、属性すごく重要。

それとLINQにはAutoIncrimentに関する操作は特にはないです。だから今度はUpdateで揉めそうです。うわー、嫌だなぁー。

5/04/2010

SilverlightでのXMLシリアライズ

どうもJudaです。

dobon.net

かずきのBlogさん

MSDN + MSDNライブラリ

waりとnaはてな日記

すまないが、XMLの書き出し、読み込みをもうちょっと簡単にしたい。

System.Runtime.Serialization.DataContractSerializer

をつかえば、なんとかなる。というか、なんとかできる。

でも正しい使い方なのかわからない。

とりあえずSilverlightでXMLを読み書きするときには、便利なクラス。

というか、XMLの解析をガチでやらせようと思うと、めんどくさくてくさくて、仕方がないです。

ありがとう、XMLの簡単な読み書き機能を作ってくれた開発者の方。

それにしてもXMLにある潜在的なセキュリティーホールとか怖いなぁ。まぁ、全ての入力はすべからく怖いのか。

4/29/2010

Silverlightとインターフェイスの話

どうもJudaです。
XAMLの技術とInterfaceの親和性についての話。
XAMLで記述して、事前にデータバインディングのターゲットを固定させて、そこへのアクセスを確率できるようなInterfaceを公開することは有益なのだろうかと言う問から端を発しました。
試作段階に置いてXAMLで表示したいものと表示の形式がある程度固まると、そのバックエンドとなる部分で調整になると思います。その時に、もっとも合致する機能はInterfaceではないのかという思いつきですが、そこそこ有益だと思います。
Interfaceなら実装を保証させるので、それによってバインディングエラーを減らすことができます。ここで注意したいのは、XAMLのほうでTwoWayを採用するなら、Interfaceに必ずSetterを書いておく方が混乱が少ないのですが、それ以外のOneTime、OneWayの場合には、それはInterfaceで規約するのではなく、実装側の裁量に任せる方がいいとおもう。また、OneWay、TwoWayの場合にはINotifyPropertyChangedの継承が実装側で最終的に必要になるので、それも検討しておきたい。
別の話にはなるが、INotifyPropertyChangedでプロパティの変更を検知する処理を組み込んで、Setterなりを修正するのだけれども、この場合には、自作でSnippet、もしくはマクロを組むことが有効であると思う。大半のコードが同一になるので、これをおすすめしたい。しかしながら、簡易でPropertyを書いた場合、つまり get;set;のプロパティへの変更検知機能の追加はめんどくさい。なんとかならないのかと思っている。
話は戻るが、Interfaceの基本的な考え方とXAMLでのバインディングの記述の間にある程度の親和性があり、これを再利用出来る形で提供すると面白いのではないかと思う。しかしこれでは何が問題になるってくるのか、まではまだちゃんと確認出来ていない。Interfaceがそういう具体性を求めているのではないとすれば、この考え方はあまり良くないと思うが、個別の開発でフロントエンドとバックエンドを分離して開発するときには、いちいち名称の確認をとらなくてもよくなって、個人的にはいいと考えた。

3/17/2010

Silverlightとの戦い

どうもJudaです。
Silverlightと最近は格闘中ですが、面白いです。TemplateやBindingはパワフルで使い出のあるアドバンテージです。これらの機能を使いこなすことでコーディング量を劇的に減らすこともできますし、自分の中のデータとビューの関係性を捉え直す機会もくれます。実に取り組みがいのある技術です。この先には、まだまだ多くの発展技術がいることを考えると、挫けそうですが。
それはそうとSilverlight4RCがきましたが、まだ確認をしていません。それよりなによりVerUpの頻度が多い気がします。それ自体は悪いことではないですが、技術書が出揃わないうちにVerUpされると出版側が手を出しにくくなって、困ります。ただでさえ、少ないのに。
ブログなどもいくつも見ていますが、重要なのは基本的な機能に十分習熟することと、Bindingをコード側からも理解することがかなり重要ですね。特にとっつきづらいのはCanvasとGridの実際的な制約事項。
Canvasは自由配置できるのですが、Grid内に配置しても自由に配置を出来ること。Gridのみの場合には、自由配置が全くできないので、XAML側での構造の構築には気を使わなければなりません。あとはDrag&Drop機能を使おうと思うときには、構造をよくよく見れば明白ですが、ListBotのListBoxItemはListBoxの外ではそのまま使えないので、取り出したあとなんらかのコンテナを必要とする点や、データ自体の受け渡しのみならば、別のItemSoruceをもつものとも融通がきくことなど。
実際にコードを触らないとあまりに些末で考えなければならないことが多いです。

1/23/2010

SilverLightことはじめ

どうもJudaです。

とりあえずSilverLightのことはじめ。

VisualStudio2008で始めるには、とりあえずSP1が当たっていること、.net Framework3.5がはいっていること。これらはWindowsのDownloadページで手にいれることができるのでこれを用意します。Visual Studio 2008 Service Pack 1 および .NET Framework 3.5 Service Pack 1

つぎにVisualStudio上でSilverLightを快適に開発するために、SilverLight Toolをいれる。Visual Studio 2008 SP1 用 MicrosoftR Silverlight(TM) 3 Tools

ほかにも便利なToolなどが存在するが、それらはCodePlexで探せばよい。

たぶん開始してProject作成をしてすぐに文字列を表示したいと思う。その際に注意がある。XAMLファイルの編集は癖があるので、注意。文字列はTextBlockを使う。ここにしか文字を書き込めない。Buttonにすらだ。つまりLabel的なものの動作はこれが請け負っている。これだけわかればあまりイライラせずに開始できるとおもう。この落とし穴に関しては解説サイトでもなんかスルーされている気がする。

開始して30分で気がつく落とし穴はそれぐらい。

12/22/2009

C#でMathematicaなIntervalの実装

どうもJudaです。
とりあえず掲題の内容を行う。
なぜ作るのか?それは必要だから。
Random関数を範囲で分散する方法に切り替えようと思うと、どうしてもIntervalって感じの区間計算クラスが欲しくなった。それ以外の用途でも、特定の定義域に値が存在しているか、いないのかを簡単なインターフェイスで取得できることをとても便利であり、よくある処理なので、これをつくる。
BoostのIntervalのAPIを参考して、なんとか作るつもり。本当に数学的な意味でのIntervalの実装は面倒なので、使い易い部分のみをサックリと。
昔似た機能のLimitというGenericClassをつくったけど、それはSerializeのためのSyntaxSuger的な糖衣クラスだったので、ちょっと今回はかっちり作ってみつつ、Serializableも目指す。
細かなクラスや機能ばかりを作っている気もするが、気にしない。大きな建築物を作るには細かな道具の手入れや資材の準備に時間を惜しまない。すべて我が血肉になるのだから。

12/10/2009

ControlController

どうもJudaです。
.net Frameworkをつかって、フォームをデザインするときにでるあの特別なコントローラーが気になります。
あれがとってもほしいのです。
考えられる方法は幾つかありますが、C#,VBがOOPと言えども、言語的にクラスの継承の間に割り込みはできないので、委譲のほうで問題を回避していくことが重要かもー。
コントロールを入れられるコントロール制御用のコンテナを用意して、そのコンテナに対して制御を加えるようにすれば、汎用的にコントロールを扱えますね。うん、というか、それ以外に思いつきません。
調べたところ、既にこのコントローラを開発した人もいるのですが、2003で作られているし、またこれに限っては車輪の再発明も幾分か自己のOOPへの理解や修練に役立つので少し試行してみる。

取り替えずコンテナをクラスで宣言します。描画の関係もあるので、Controlを継承した方が無難なので、継承する。ただここで考えるのは、
・これにコントロールを入れて、
・Mouse系のイベントを使うこと、
・Key系のイベントでの制御も許容すること。
・同時に周りのコントロールとの数値の関係性によって拘束がかかること。
・選択時には特別な描画処理を行うので、Paintイベントも書くこと。
意外と使い易いコンテナをつくるには問題がありそうだ。
コントロールをコンテナに格納したときに、格納したクラスの個別のマウスやキーのイベントをハックしないといけないので、これが若干気になりますねー。コンテナ格納後に個別のコントロールのイベントが生きていると困るので、殺しておきたいのですが、よくわからないのであとで調べておきますね。
たぶん内側を透明にしてZバッファの順序を入れ替える。もしくはフォーカスイベントが発生するとフォーカスを移すとかですけど、フォーカスのイベント内でフォーカスを移動させると予想外の動きをするので、あまりおすすめできません。以前、実験した際に、呼び出しが規則的に発生しないことを確認したので、フォーカスを制御するのは、確実性に疑問があるので、別の方法を模索するほうがいいです。
あとはコントロールが登録されているものを入れ替えてしまうかですが、これはデータの構造を勝手に書き換えることになるので、おすすめできません。汎用性にかけることは間違いないので、なるべく同一の階層性でイベントの登録のみで解決したいですね。
…別にコンテナを開発しなくても、イベントの登録、削除をうまく制御すれば、データ構造的な面では出来そうですが、すでに存在しているイベントとぶつかったり、そもそももとのイベントが駆動してしまう問題があるので、これはうまくいきそうにないです。
ここまでの問題点で一番大きいのは、コントロールに発生するイベントを一時的に殺して、それをバイパスして別のコントールに移すことができるのかどうかです。そのあとは、ここの機能を分割しながら実装していけば問題はなし。
初回ではなく、選択後つまりコンテナに入れられた後に、そのあとは独占的にコントロールを支配できなければいけません。なにか方法はないものでしょうか?

4/26/2009

C++の技術本を少々

買いました。
Exceptional C++―47のクイズ形式によるプログラム問題と解法 (C++ in‐Depth Series)
Accelerated C++―効率的なプログラミングのための新しい定跡 (C++ In Depth Series)
Modern C++ Design―ジェネリック・プログラミングおよびデザイン・パターンを利用するための究極のテンプレート
合計で7000円超也
ちょいと本気で業務でC++使っていくなら、知っておくべきかと思って買ってみました。

"こんな本を読まなくてもC++ぐらい使えるようになる。"
ごもっともです。8割方もう趣味です。言語マニアですな。何度も言うけど、本当はC++よりもC#を愛しています。でも業務で使えないので、仕方なくC++をやっています、今は。まぁ使っていくと、それほど面倒でもなくなってきました。ですが、どうしてもC#の便利さに慣れているので、Propertyの存在やtry-catch-finallyの便利さが懐かしいです。あとは超強力リファクタリング機能。言語的な特性よりも開発環境からのサポートの強力さがC#Loveを推進しています。
現在はいまひとつ分かっていないC++のTemplate機能とSTL、Boostの使える機能。この二つをおさえれば、もう少し開発が楽になると思うので、前述の本を買いました。Boostの本は中古がなかったので、本屋で買おうと思っています。C#のほうはすでにオライリー本があるので、これ以上は買いませんが、いまだに効率的な例外処理クラスとカスタム属性がつかめていません。あとはラムダとヴァリアント。C#3.0を早いうちに慣れさせたいのですが、C#2.0ですら使わせてもらえないので、遅遅として進まないのが目下の問題です。

4/05/2009

AssertとException

アサートとエクセプション

ついさっき、AssertとExceptionの違いを理解した。

端的にいって

  1. AssertはDeveloperのためのもの。
  2. ExceptionはUserとDeveloperのためのもの。

Assertは前からその存在を知っていたのだが、うまく使い方が分からずにずっと放置していた。

とりあえず自分で考えた使い方のルールを備忘録。

  1. Publicなメソッドの中での引数のエラーなどは、Exceptionで処理するか、もしくはそのまま情報を追加してThrowする。
  2. Privateなメソッドの中での引数のエラーなどは、基本的に開発者に責任があるので、それはAssertで警告する。
  3. ProtectedなメソッドでVirtualでないものは基本的にAssert、それ以外はException。
  4. DLLなどの形のときに外部から使われるものは、基本的にはThrowする。それ以外は開発者のみが知ればいい情報なので、それらはAssertで処理する。

例外処理が万能すぎるからついつい多用してしまうので基本的にはこのルールでいいと思う。Trace…に関しては別の話でw。

あと問題だと思うのは、Exceptionでしか捕捉できないもので、なおかつAssertしたほうがいいものがあるけど、これはどうするのか…それとそもそも予期できないエラーはすべてExceptionに飛んでいくのはどうなのだろう…。プログラムの設計の仕方が悪いのかもしれない。

安全で、効率的なコーディングを目指してT&Eしかないのか…

3/31/2009

日々、吾ハ習ヒ試シ違ヒ試スナリ: .NET Framework のDictionaryの弱点

日々、吾ハ習ヒ試シ違ヒ試スナリ: .NET Framework のDictionaryの弱点

この記事の話ですが、
よくよく調べるとDictionaryEntryの配列が存在しました。
こいつは、PropertyがKey,ValueともにGetSetなので、
期待しているSerializeの働きを行うのに適合します。
これによってデータがSerialize、Deserializeされることが
確認できましたので、覚書ですが、ここに記します。

3/04/2009

.NET Framework のDictionaryの弱点

Dictionaryの弱点というか、クラスの設計上の弱点という盲点だと思うけど。

Serializeすることができない。

答えは復元することができないからだ。

KeyValuePairでのKey、ValueのそれぞれはGetしかできないので、その後の復元ができないのだ。しかし辞書クラスは外部にデータを取り出したい、ときもある。
しかもややこしいことに大体この一対一のペアになるようなデータ構造のものは結構あるという罠。
かといって、このために新たに構造体を作るのもなにか負けた気がする。

解決策は...わかりません。
さらに問題なのは、IFormatConverterとかいうSerializeのための変換インタフェイスがあるのですが、実装しなおさなければならないということ。GenericClassなんだから最初から実装してよ、って思いました。

PS. 
もうどうしようもないので、拡張してしまった先の話
PS.2
このようなTopicに関する議論。ところどころ
冗長だと思うけど。

構文解析

数式の解析はだいたい正しく組めるようになった。
重要なのは、スタックの優先度が低いものから高いものへの再起構成かなぁ・・・
あとはOutOfIndex(w

ただこの数式の解析については基本の演算子のみサポート
代入"="と等号不等号の演算子には非対応。

これらに関しては、数式とは別のレベルでの解析が必要になる。
代入と成否判定はもっと単純に表現すると、
X=AとA==Bなどの形式に変換されて、Xは変数、A、Bはそれぞれが数式である。
このときの記号はVerb(動詞)として振舞う。
そして動詞の振る舞いも自動詞、他動詞がある。
自動詞ならば X(arg1,arg2,...argN)
他動詞ならば A?B
だなぁ。
?は予約された記号で対応できそうだな・・・
まぁ、変数の宣言機能はつけなければどうでもいいかもなぁ。

自動詞と他動詞のたとえだと若干混乱するけど、言いたいのは記号の動詞的振る舞いだから、そこに注意。

3/02/2009

数式エンジン

どうもJudaです。
数式エンジンをようやく作れました。
計算は逆ポーランド記法にしたがって記述しなおしながら行いました。
変数の取得と代入もIronPythonの方式で行えるようにしました。

ただし新規に登録できる機構がついていないので、使い方は大体Shaderみたいな感じ。
これによって一列の数式なら計算可能になりました。
あとは構文解析を行ってIfStatementによる条件分岐が行えるようになれば、簡易のスクリプトエンジンとしては十分かなぁっと。
そのときには変数の宣言が必要になると思うし、また例外処理の厳密化が問題になると思う。

ちょっと思ったのですが、計算の演算子の優先順位で%と^の優先順位がどのようになっているのか。
今回のエンジンは () > ^ > */% > +- > = の順番で優先順位がついているのですが、これであっているのでしょうか?
まぁ ^ が今回特別に必要なので追加しましたが、これでいいのだろうか?

2/28/2009

自前の計算用のインタプリタ

ちょっとした計算を外部に出したいってことがある。
そのために外部変数を取り入れ可能なインタプリタエンジンがほしい。
IronPythonもあるけど、あれは便利だけど、でかすぎる。
もっと機能限定された簡単なものでいいのだ。

ということで、
『ゲームプログラミングエンジン』赤坂玲音著、Softbank Publishing
『プログラミング作法』Brain W.Kernighan,Rob Pike著、福崎 俊博訳、ASCII出版
に出てくるインタプリタの項目を参考にして作成中。

とりあえず考え方は分かるのだけど、いかにして言語化するのかについて思案中。
基本的な算術式を実行できるようにするだけでなかなか大変だなぁ。
でも一度作れば、自分の資産になるので、勉強中。

現在、まさにこの勉強にぴったりな内容の本が出版されているので、
興味のある方はそちらを探してみるのもいいでしょう。

別の話
RIDEBACKがアニメ化されているけど、おもしろい。
10巻で最終巻らしいが、さっさと戦争状態に入ってしまったので、かなしい。もっとレースの話をしてくれても楽しかったかも。

2/27/2009

IronPythonへの移植

Pythonコードへの外部化に成功した。
今回ネックになったのは、DLLのImport
そもそも名前空間だけ異なる同じプロジェクト内に存在するファイルのクラスをどのようにして認識させるのか分からなかったので、そもそもそれはDLL化した。
まぁそこまでやると普通のDLLの登録と変わらない。
AssemblyNameはdllのプロパティからデータを取って、妥当性チェックをすることができる。名前空間のImport自体はオブジェクトブラウザにDLLを食べさせることができれば問題なくできる。
ただPythonのコード自体の妥当性チェックに有効な方法があまりないのが現状で、このコンパイルエラーをより厳密に特定できるようになれば、生産性は格段にあがると思う。
あとは、ImportのSyntaxSugerがもっとほしいとは思う。
とりあえず前のエントリの情報に従っていけば、IronPython1.1は十分エンジンとして組み込み可能なことが分かった。ただやはりハードコーディングのほうが実行速度は速い。事前コンパイルのエンジンを駆動させることができればより早くなる可能性はある。要検討だと思う。