2010年02月07日
ナノピコ教室のプログラムをSilverlightアプリへ (2)
1月10日に、「ナノピコ教室のプログラムをSilverlightアプリへ」というエントリで、以前書いた「オセロ最短詰め」「数独を解く」「梅花碁」「8クイーンゲーム」「面積最大の領域」などのプログラムを Silverlightアプリに移植するのに、盤データを扱う共通のクラスを作成するつもり、と書きましたが、昨日、今日はまとまった時間が取れたので、なんとか形になりました。
Boardクラスと、BoardCanvasという2つのクラスが中心となるクラスです。
Boardクラスは、盤データを扱うモデルクラス。
BoardCanvasクラスは、描画を担当するビュークラス。
このクラスの動作を確認するのに簡単なプログラムを書いたのがこれ。
ボード上をクリックすると、黒石→白石→消去を繰り返します。
Boardクラスと、BoardCanvasのソースコードはこちらに掲載しています。
デモプログラムのソースコードは、こちらです。
描画は、カスタムコントロールで、Boardオブジェクトとバインドできれば良かったのですが、まだSilverlightの知識が足りないので、通常のクラスとして、BoardCanvasクラスを作成しています。
ここまで出来れば、各プログラムのSilverlightへの移植は、それほど難しくないかなーと思ってます。
Boardクラスと、BoardCanvasという2つのクラスが中心となるクラスです。
Boardクラスは、盤データを扱うモデルクラス。
BoardCanvasクラスは、描画を担当するビュークラス。
このクラスの動作を確認するのに簡単なプログラムを書いたのがこれ。
ボード上をクリックすると、黒石→白石→消去を繰り返します。
Boardクラスと、BoardCanvasのソースコードはこちらに掲載しています。
デモプログラムのソースコードは、こちらです。
描画は、カスタムコントロールで、Boardオブジェクトとバインドできれば良かったのですが、まだSilverlightの知識が足りないので、通常のクラスとして、BoardCanvasクラスを作成しています。
ここまで出来れば、各プログラムのSilverlightへの移植は、それほど難しくないかなーと思ってます。
2010年02月03日
NotifyIconの左クリックでコンテキストメニューを表示させる
System.Windows.Forms.NotifyIcon クラスを使うと、通常、右クリックでコンテキストメニューが表示されます。
これを右クリックではなく、左クリックでコンテキストメニューを表示させるサンプルコードです。
privateメソッドを呼ぶという、かなり強引でトリッキーなやり方ですが、うまく動いています。
デザイン時には、notifyIcon1.ContextMenuStrip プロパティには、何も設定しません。
このやり方の場合、メニューが表示されているときに、デスクトップ領域をクリックすると、メニューが消えてくれます。
contextMenuStrip1.Show() だと、メニュー項目を選ぶまで消えてくれません。
それと、Clickではなく、MouseUpイベントで行うのがよさげです。
これを右クリックではなく、左クリックでコンテキストメニューを表示させるサンプルコードです。
privateメソッドを呼ぶという、かなり強引でトリッキーなやり方ですが、うまく動いています。
デザイン時には、notifyIcon1.ContextMenuStrip プロパティには、何も設定しません。
このやり方の場合、メニューが表示されているときに、デスクトップ領域をクリックすると、メニューが消えてくれます。
contextMenuStrip1.Show() だと、メニュー項目を選ぶまで消えてくれません。
それと、Clickではなく、MouseUpイベントで行うのがよさげです。
2010年01月31日
エントリ・ポイントを含むアセンブリ(Assemblyオブジェクト)を取得
以下は、現在実行されているアセンブリのバージョンを得るコードです。
GetName() というメソッド名が紛らわしいんですよね。
GetName()で返るのは、文字列ではなく、System.Reflection.AssemblyName クラスの インスタンスです。
GetExecutingAssembly の代わりに、GetEntryAssembly を使えば、 エントリポイント(Mainメソッド)を含むアセンブリの情報を取得できます。
クラスライブラリ側で、実行中のexeのアセンブリ情報を利用したい場合に使えます。
以下のコードは、バージョン情報を得るコードです。
もちろん、そのパス名や、アセンブリ表示名も取得できます。
GetName() というメソッド名が紛らわしいんですよね。
GetName()で返るのは、文字列ではなく、System.Reflection.AssemblyName クラスの インスタンスです。
GetExecutingAssembly の代わりに、GetEntryAssembly を使えば、 エントリポイント(Mainメソッド)を含むアセンブリの情報を取得できます。
クラスライブラリ側で、実行中のexeのアセンブリ情報を利用したい場合に使えます。
以下のコードは、バージョン情報を得るコードです。
もちろん、そのパス名や、アセンブリ表示名も取得できます。
2010年01月23日
再帰メソッドで、yield returnしたい
再帰メソッドの戻り値を IEnumerable<T>にする場合についてまとめてみました。
順列を列挙するプログラムを例に説明します。
まず、以下のコードを見てください。
このコードの問題点は、_GetPermutations というメソッドの中で、Printメソッドを 呼び出している点です。
これだと、順列を求めるコードと、求めた順列を使って処理をするコードを明確に 分離することができません。
Permutationクラスは、いろんな場面で使える構造になっていないわけです。 問題が異なれば、Printメソッドの部分を書き直さなくてはなりません。
これを解決する方法のひとつが、イベントやdelegateを使う方法です。
順列が求まるたびに、イベントを発行すれば、Permutationクラスの利用者が Permutationクラスに手を入れることなく、自由に独自の処理を書くことができます。
ただ、この方法にも欠点があります。
例えば、GUIのあるプログラムで、次へボタンを押すたびに、順列をひとつずつ表示する ことを考えて見ましょう。こういった要求には、イベント発行する方法は上手く対応する ことができません。
Permutationクラスの利用する側で、Next メソッドなどを使い、ひとつずつ取り出せれば 良いですよね。
それには、Enumerate メソッドの戻り値を、IEnumerable<T>にするのが良さそうです。
以下に、戻り値を、IEnumerable<T> にしたPermutationクラスを示します。
注目すべき点は、再帰メソッドを呼び出して、返ってきた戻り値の扱いです(★印)。
return result とは書けません。
foreachで、一つ一つ要素を取り出し、yield return しています。こうすることで、再帰メソッドで、戻り値をIEnumerable<T>にすることができます。
全ての結果を Listなどに溜め込む方法でも、Enumerateメソッドの戻り値をIEnumerable<T>に出来ますが (この場合は、下請けメソッドの_GetPermutationsの戻り値は、IEnumerable<T>にはなりません)、 全てを列挙し終わらないと、Enumerateメソッドから制御を戻せませんので、 順列の元となる要素数が多い場合には、最初のひとつを取り出すのにも多くの時間を 要してしまい好ましくありません。
では、これを使う側のコードを示します。
まずはforeachで取り出すコード
次に、IEnumerator<T>.MoveNext, IEnumerator<T>.Currentを使うコード
ボタンをクリックするごとに、次の順列を取り出し、labelに表示しています。
順列を列挙するプログラムを例に説明します。
まず、以下のコードを見てください。
このコードの問題点は、_GetPermutations というメソッドの中で、Printメソッドを 呼び出している点です。
これだと、順列を求めるコードと、求めた順列を使って処理をするコードを明確に 分離することができません。
Permutationクラスは、いろんな場面で使える構造になっていないわけです。 問題が異なれば、Printメソッドの部分を書き直さなくてはなりません。
これを解決する方法のひとつが、イベントやdelegateを使う方法です。
順列が求まるたびに、イベントを発行すれば、Permutationクラスの利用者が Permutationクラスに手を入れることなく、自由に独自の処理を書くことができます。
ただ、この方法にも欠点があります。
例えば、GUIのあるプログラムで、次へボタンを押すたびに、順列をひとつずつ表示する ことを考えて見ましょう。こういった要求には、イベント発行する方法は上手く対応する ことができません。
Permutationクラスの利用する側で、Next メソッドなどを使い、ひとつずつ取り出せれば 良いですよね。
それには、Enumerate メソッドの戻り値を、IEnumerable<T>にするのが良さそうです。
以下に、戻り値を、IEnumerable<T> にしたPermutationクラスを示します。
注目すべき点は、再帰メソッドを呼び出して、返ってきた戻り値の扱いです(★印)。
return result とは書けません。
foreachで、一つ一つ要素を取り出し、yield return しています。こうすることで、再帰メソッドで、戻り値をIEnumerable<T>にすることができます。
全ての結果を Listなどに溜め込む方法でも、Enumerateメソッドの戻り値をIEnumerable<T>に出来ますが (この場合は、下請けメソッドの_GetPermutationsの戻り値は、IEnumerable<T>にはなりません)、 全てを列挙し終わらないと、Enumerateメソッドから制御を戻せませんので、 順列の元となる要素数が多い場合には、最初のひとつを取り出すのにも多くの時間を 要してしまい好ましくありません。
では、これを使う側のコードを示します。
まずはforeachで取り出すコード
次に、IEnumerator<T>.MoveNext, IEnumerator<T>.Currentを使うコード
ボタンをクリックするごとに、次の順列を取り出し、labelに表示しています。
2010年01月17日
シェルピンスキーのギャスケット
2010年01月14日
LINQ to XML 目次
2010年01月10日
ナノピコ教室のプログラムをSilverlightアプリへ
随分昔に出版された『ナノピコ教室・プログラミング問題集』(駒木悠二+有澤誠 編 共立出版株式会社)に掲載されている問題をC#で解いたものを、昨年前半にこのブログで紹介しました。
現在、これらのプログラムを再度見直し&修正して、
Gushwell's C# Programming Pageの「C#プログラム小品集」に移そうとしているところです。
すでに、いくつかは移したのですが、
「オセロ最短詰め」「数独を解く」「梅花碁」「8クイーンゲーム」「面積最大の領域」などは、せっかくなのでコンソールアプリからSilverlightアプリに書きなおしブラウザ上で動作を確認できるようにしようと考えています。
これらのプログラムはすべて2次元の盤データを扱うのですが、それぞれ、その時の気分でBoardクラスを作成していたので、この際、すべてに共通する BoardBaseクラスを書き、これから派生させて使うようにしようと検討中。
そうすれば、今後、2次元のデータを使うBoardクラスを書く際は、このBoardBaseクラスが使えることになりますし、
僕の書いたコードで学習しようとしている人(そんな人がいるのかというのは置いといて...)にとっても、似たようなコードを何べんも読み解く必要が無くなるので良いのかな。
ついでに、画面の描画もBoardCanvasというクラスを作り共通化しようとしています。
そして、
board[x,y] = BlackPiece; // x,yの位置に黒石を置く
と書くと、モデルであるBoardオブジェクトが変更されるとともに、画面も更新させられればGood。
Boardクラス内でイベントを発生させ、BoardCanvasでイベントを受け取り、描画させればいいかな。
細かな点は、いろいろ試行錯誤して決めていくつもり。
ところで、Silverlightをいじり始めた時は、Paintイベントが無いのに違和感がありましたが、パネルオブジェクトに対し、
panel.Children.Add(element);
とか
panel.Children.Remove(element);
とするだけで、描画/消去ができるのは、思いのほか便利だと感じ始めています。
現在、これらのプログラムを再度見直し&修正して、
Gushwell's C# Programming Pageの「C#プログラム小品集」に移そうとしているところです。
すでに、いくつかは移したのですが、
「オセロ最短詰め」「数独を解く」「梅花碁」「8クイーンゲーム」「面積最大の領域」などは、せっかくなのでコンソールアプリからSilverlightアプリに書きなおしブラウザ上で動作を確認できるようにしようと考えています。
これらのプログラムはすべて2次元の盤データを扱うのですが、それぞれ、その時の気分でBoardクラスを作成していたので、この際、すべてに共通する BoardBaseクラスを書き、これから派生させて使うようにしようと検討中。
そうすれば、今後、2次元のデータを使うBoardクラスを書く際は、このBoardBaseクラスが使えることになりますし、
僕の書いたコードで学習しようとしている人(そんな人がいるのかというのは置いといて...)にとっても、似たようなコードを何べんも読み解く必要が無くなるので良いのかな。
ついでに、画面の描画もBoardCanvasというクラスを作り共通化しようとしています。
そして、
board[x,y] = BlackPiece; // x,yの位置に黒石を置く
と書くと、モデルであるBoardオブジェクトが変更されるとともに、画面も更新させられればGood。
Boardクラス内でイベントを発生させ、BoardCanvasでイベントを受け取り、描画させればいいかな。
細かな点は、いろいろ試行錯誤して決めていくつもり。
ところで、Silverlightをいじり始めた時は、Paintイベントが無いのに違和感がありましたが、パネルオブジェクトに対し、
panel.Children.Add(element);
とか
panel.Children.Remove(element);
とするだけで、描画/消去ができるのは、思いのほか便利だと感じ始めています。
2010年01月09日
メルマガ:C#プログラミングレッスン 読者数1900名突破
メールマガジン「C#プログラミングレッスン」の購読者数が 1900名を突破しました。\(^^)/
購読してくださっている方、どうもありがとうございます。
目標の2000名突破が見えてきました。
このペースだと、5月頃にはクリアできそうです。
1月12日(火)からは、新しい連載「どう書くorg編」が始まります。
どうぞご期待ください。
購読してくださっている方、どうもありがとうございます。
目標の2000名突破が見えてきました。
このペースだと、5月頃にはクリアできそうです。
1月12日(火)からは、新しい連載「どう書くorg編」が始まります。
どうぞご期待ください。
2010年01月07日
String.PadLeft
MSDNのクラスライブラリリファレンスを見てたら、
こんなメソッドがあるのを知りました。
PadLeftは、文字を右寄せし、指定した文字数になるまで、
左側に空白または指定した文字を埋め込んでくれます。
とすると、
と表示されます。
同様に、PadRight という右側に文字を埋め込むメソッドもあります。
こんなメソッドがあるのを知りました。
PadLeftは、文字を右寄せし、指定した文字数になるまで、
左側に空白または指定した文字を埋め込んでくれます。
とすると、
と表示されます。
同様に、PadRight という右側に文字を埋め込むメソッドもあります。
2010年01月03日
新年のご挨拶
皆さん、あけましておめでとうございます。
今年も「窓際プログラマーの独り言」「Gushwell's C# Programming Page」「C#プログラミングレッスン」をよろしくお願いします。
今、メールマガジン「C#プログラミングレッスン」の新連載「どう書く?.org編」の構想を練っているところです。
何を取り上げるのかを決めるのに意外と手間取っています。
たぶん、「どう書く?.org編」を4カ月ほど続け、そのあとに、(Visual Studio 2010 がいつ発売されるかにも因りますが)、C#4.0, .NET4 関連の話題を取り上げられればいいかなと思っています。
それと、Gushwell's C# Programming Pageの「C#プログラム小品集」をもっと充実させたいと思います。
この2つでかなりの時間を割くことになりそうな予感。
このブログも皆さんに忘れられないように更新していければと思います。
今年も「窓際プログラマーの独り言」「Gushwell's C# Programming Page」「C#プログラミングレッスン」をよろしくお願いします。
今、メールマガジン「C#プログラミングレッスン」の新連載「どう書く?.org編」の構想を練っているところです。
何を取り上げるのかを決めるのに意外と手間取っています。
たぶん、「どう書く?.org編」を4カ月ほど続け、そのあとに、(Visual Studio 2010 がいつ発売されるかにも因りますが)、C#4.0, .NET4 関連の話題を取り上げられればいいかなと思っています。
それと、Gushwell's C# Programming Pageの「C#プログラム小品集」をもっと充実させたいと思います。
この2つでかなりの時間を割くことになりそうな予感。
このブログも皆さんに忘れられないように更新していければと思います。
