新年一発目は
新年一発目は、昨年からずっと書きたくて放ったらかしになっていたやっとVisual
BasicでWPFを書く気がするようになる!!with
Visual Basic 2010 の新機能を今更ながら書いてみます。
*新機能一覧のリンクは青柳さんのブログ
私が以前書いた元ネタ(【Love
VB】 レッツWPF M-V-VM モデル )では、VBをdisりまくってます^^;
なぜならば、
複数行のラムダ式がなかったため、デリゲート部をそのままラムダ式にしていたC#用サンプルが単純なコピペでは利用しにくい問題があったからです。いちいちデリゲート先の関数を別途書くのがややこしくて面倒に感じたため、C#に浮気を....。これがようやっと出来るようになりました^^。でも、非常にキショい書き方になります。詳しくは本文
*元ネタの元ネタ:[WPF][C#]Model
View ViewModelパターンでハローワールド (かずきさんのBlog)
http://blogs.wankuma.com/kazuki/archive/2009/02/23/168586.aspx
本投稿では、Visual Basic 2010(以下VB10)の新機能(MSDN)のうち以下の3つを扱います
・複数行のラムダ式(これで、やっと.NET 3.0以降をVBで書く気がしてきました^^)
・自動実装プロパティ(プロパティなんてPublicでイイじゃん?文化から脱却する時がきました)
・暗黙的な行継続(微妙に制約があってわけワカメ。業務上の記述標準ではLINQ以外スルーの予定^^;)
では、早速作っていきます。従来と同じところは基本的にコピペの方向で(手抜きじゃないよw)
【お約束】Visual Studio 2010のβ2を使用しています。製品版ではもっと良くなってると思われます。予めご了承ください。
「VB 10で作るM-V-VMモデルなHello World^^」
1、WPFMVVMHelloWorldという名前でWPFアプリケーション(当然VB!)を作成
暗黙的な行継続のおかけで、仮引数宣言部や代入部などのアンスコをいれた改行部分では、アンスコを脱がしてやらないとコンパイラが「識別子が必要です。」なんてご機嫌ナナメになってしまいました。曖昧さがないと公知出来る部分はアンスコなしでOKになりました^^
できるだけ外しくなるVBの気持ちは男としてよく分かるが、Hentaiっぽくてキショい。
(*要編集だったのは、元ネタのHTML<br>が改行されなかった模様^^;)
【例】
●VB9
AddHandler(ByVal value
As EventHandler)
Me._CanExecuteChanged = _
CType(System.Delegate.Combine(Me._CanExecuteChanged, value), EventHandler)
AddHandler CommandManager.RequerySuggested,
Me._CanExecuteChanged
End AddHandler
|
↓
●VB10(アンスコがひん曲げられて、脱がせて真下へ移動させろとうるさいorz)
カスタムイベントの文法がウザイのはVB10になっても相変わらず><
*デレゲートやイベントまわりの美しさはC#に敵わんorz
自動実装プロパティで楽々^^。(Publicでいいんじゃね?とかはもう無しの方向でw)
【例】
●VB9
Public Class Person
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
End Class |
↓
●VB10(自動実装プロパティでウザい下駄・雪駄から開放^^)
Public Class Person
Property Name AsString’Publicつけなくてもパブリックのスコープを持ちます
End Class |
4、ViewModelの作成
複数行のラムダ式で、やっとC#のサンプルを文法の置換えでVBから利用できるようになりました^^
引っかかった点として、あくまでも「複数行」のラムダ式なので、一行で書いた場合は従来通り「式」として扱われることです。ステートメントとして扱いたい場合は単一行のサブルーチン形式で記述します。詳しくは続編をご覧下さい(2010/1/7追記)
【例】
●VB9(従来ラムダ式内は式のみでステートメントが書けないため、別途メッソドを作成)
Public ReadOnly
Property CreateMessageCommand()
As ICommand
Get
' 作成済みなら、それを返す
If Not IsNothing(_createMessageCommand)
Then
Return _createMessageCommand
' 遅延初期化 ' 今回は、処理が単純なのでラムダ式で全部書いたが、通常は
' ViewModel内の別メソッドとして定義する。
'VBでもラムダ式で...ぼけ、かす、あほ(やばい、VBへの愛が...
'Function式なので、なにがしかの戻り値が必要。んでもって...。
'Me.Message = string.Format("こんにちは{0}さん", Me.Name)
'ラムダ式では、これは代入じゃなくて比較を意味するんですねこのくそボケは(使えんorz)
'心の叫び誰か「てめぇの書き方が間違ってる!!」ってdisってぇ(できればメガネ女子)
_createMessageCommand = New DelegateCommand( _
AddressOf
updateMessage, _
Function(param)
String.IsNullOrEmpty(CType(Me, IDataErrorInfo)("Name")))
Return _createMessageCommand
End
Get
End
Property
'諦めてメソッド作りましょうorz
Private
Sub
updateMessage()
Me.Message =
String.Format("こんにちは{0}さん",
Me.Name)
End
Sub
|
↓
●VB10(ステートメントにしたければ、何故か改行してEnd
Functionまで書かないとダメ)
*以下の太字斜体部のように1行で書いてもコンパイルエラーはでないが動きません。
■動かなくて悩んだ例(コンパイル時にエラーは出ません。従来通り式として扱われます)
'VBでもラムダ式で...書けます^^
_createMessageCommand = New DelegateCommand(
Function(param)
Me.Message =
String.Format("こんにちは{0}さん",
Me.Name),
Function(param)
String.IsNullOrEmpty(CType(Me, IDataErrorInfo)("Name")))
|
■動いた^^(でも、そのままではFunction"<匿名メソッド>"に戻り値がない、と警告が出ます。キショいorz)
ということで、Return Nothing入れるなど。または単一行のサブルーチン形式で記述します詳しくは続編をご覧下さい(2010/1/7追記)
Public ReadOnly Property CreateMessageCommand() As ICommand
Get
' 作成済みなら、それを返す
If Not IsNothing(_createMessageCommand) Then Return _createMessageCommand
' 遅延初期化
' 今回は、処理が単純なのでラムダ式で全部書いたが、通常は
' ViewModel内の別メソッドとして定義する。
'VBでもラムダ式で...出来ます^^
_createMessageCommand = New DelegateCommand(
Function(param)
Me.Message = String.Format("こんにちは{0}さん", Me.Name)
Return Nothing
End Function,
Function(param) String.IsNullOrEmpty(CType(Me, IDataErrorInfo)("Name")))
Return _createMessageCommand
End Get
End Property |
5、View(UserControlクラス「HelloWorldView」)の作成
相変わらず、デフォルトではVBでは頭に既定の名前空間が勝手につくので、C#のサンプルなどから貼りつけるときは既定の名前空間を外してコピペしてください。
6、ViewとViewModelの結合
●Application.xamlのコピペ(ビルドしないと、クラスが見つからないといわれます)
●MainWindow.xamlのコピペ
*プロジェクト作成時にできるWindowのクラス名がWindow1からMainWindowに変わっています。
xaml内のクラス指定もWindow1からMainWindowに変更してください
(MainWindowだなんてSilverlightの影響!?)
7、仕上げ
Application.xaml.vbをコピペして終わり^^
*IDEのイベント作成機能を使うと、宣言後ろにHandlesが付きます。これをつけっぱなしにしていると、XAMLで定義したものと2回呼ばれてしまいますので、Handlesを外しましょう。
8、実行
応答なしでプロジェクトがぶっ飛ぶ前にセーブしましょう^^;
セーブ前にぶっ飛んでも、以下のディレクトリに残ってるかもしれません。
%UserProfile%\AppData\Local\Temporary Projects