2009年11月17日火曜日

意図しないDataTemplateが適用されたケース

今回も悩んだ話。
たぶん自分で作ったプログラムとか慣れた人の場合ならつまづかないんだろうけど、
他人の作ったプログラムを見ていた時の話。
新しく作ったクラスに
DataTemplateでDataTypeとかちゃんと設定しているはずなのに
違うDataTemplateが適用されてしまうということがありました。
探し回ったら
ItemTemplateSelector
が別途設定されていました。。

2009年11月8日日曜日

Bindingがうまくいかなくてハマッタ話

ハマッタ話ばっかりですね。。(汗
今日も短いです。

Text="{Binding Path=DisplayString}"

として確実にDisplayStringがあるはずなのに表示されなかった事件!
ちゃんとイミディエイトウィンドウではobj.DisplayStringみたいにして見れるんです。

今回もすごく間抜けな原因で、
class XXX {
   public string DisplayString;
}
としていました。
簡単ですね。
Binding は 『プロパティ』に対してしなければならないので
class XXX {
   public string DisplayString {set; get;}
}
としただけで解決しました。

2009年11月6日金曜日

Listboxで選択状態がおかしい!のハマッタ話

今回のは単純すぎというかまぬけすぎて書くかどうか迷ったのですが、
Listboxでたとえば3つのアイテムA,B,Cがあって、
ふつうはA選択中にBをクリックするとBが選択される。
今回の失態は、A選択中にBをクリックするとA,Bが選択状態になる、というもの。

SelectionModeとか余計なものが頭をよぎったのですぐにわからなかったのですが、
単純にoverrideしたEqualsが誤ってA==Bとなるようになっていたのでした。。

2009年11月4日水曜日

Filter更新のタイミング

ListBoxなどのリストで表示したくないアイテムがあるときはFilterを使います。
ですが、Filterを後からかけ直す方法がわからずこの数日四苦八苦してました。
具体的には、


  IsDisplay == false;


のときアイテムを非表示にするようなListboxで、
リストに追加するときの状態でフィルタがかかりますが、
すでに表示中のIsDisplayをfalseに書き換えても、
フィルタは再度かからないという状態でした。

解決方法は、
表示するアイテムをINotifyPropertyChangedにするなりして、
変更を検出できるようにする。
変更を検出したら


CollectionViewSource.GetDefaultView(リストのインスタンス).Refresh();



などで更新をしてやること。

でした。
スマートではないような気がしますが、一応解決ということで。

2009年10月26日月曜日

ApplicationDefinition 要素を指定できません。エラー

今日はこのエラーに2時間くらい悩まされました。。(汗
C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.WinFX.targets(294,9): error MC1002: ライブラリ プロジェクト ファイルは、ApplicationDefinition 要素を指定できません。
C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.WinFX.targets(294,9): error BG1003: プロジェクト ファイルに、無効なプロパティ値が含まれています。


で、見つけたのがこのQ&A

簡単に書くと、
1.WPFアプリをライブラリに変更した後にapp.xamlやapp.xaml.csが残っていたらおかしくなるぜー
のケースと
2.ファイルをコピペしたらビルドアクションがおかしくなるぜー。xamlファイルを右クリックしてビルドアクションプロパティをApplicationDefinitionからPageにかえな!
のパターンみたいです。

わたしの場合は2で、さらにpngのビルドアクションはResourceからPageに勝手に変わっていたので
全部Resourceに直しました。

2009年10月20日火曜日

Bindingが反映されなくてではまった話

TextBoxをおいてTextプロパティを適当にバインディングしたのに反映されない、
Source→Targetにも、逆にも、まったく反映されないということで今日結構な時間つまっていました。

まぁこれも解決してしまえば簡単な話で、
TextBoxにTemplate="{StaticResource ~~~
なんて余計なものを書いているのを忘れて、実際にはTemplateのなかのものが表示されている
(もちろんTemplateは適切に作れていない)というだけでした。

最近こういう間抜けな話だけのブログになりつつあるな。。

便利:メソッドスタブの作成

いや、もうたぶん常識なのでしょうけど。。
今までユニットテストを作成するとき、ずっと

1.対象のクラスVMをクラスだけ作成
2.VMをテストするVMTestクラスを作成
3.VMクラスに空のメソッドFix()を作成
4.VMTestクラスにFix()をテストするコードを記述
5.VMのFix()の中身を実装
6.メソッドごとに3~5を繰り返し

のようにやっていました。
結構空のスケルトンを作るためだけに
テスト対象の本物のクラスに戻るのがめんどくさかったんですけど、(3のところ)
テストクラスの方でメソッドを作ったときに





のように表示され、もちろんまだ存在しないFix()メソッドは警告の波線がついているわけですが、
ここでメソッド名の下の青い四角を押すと







のようになんと(VMクラスに移動することなく、)スタブをその場で作成することができます。
これでクラスを移動する回数がかなり減りました!

きっと常識なんだよね。。。

小さな発見でしたが、大きな効率化になりそうです♪

2009年10月18日日曜日

ClassInitialize()で実行時エラー

Windows7とVisual Studio2010に環境移行したので、前回の日記から間が開きました。

テスト環境もNUnitからVS2010のUnitTestFrameworkに移行しようとしました。

で、VSで単体テストクラスのスケルトンをはいて実行したところ、

メソッド (プロジェクト名).(クラス名).MyClassInitialize は不適切なシグネチャを含んでいます。パラメーター 1 は型 Microsoft.VisualStudio.TestTools.UnitTesting.TestContext でなければなりません。

と。
コードを何度見直しても間違いはない。というかスケルトンからシグネチャは変更していない。

で、ネットで検索したらこういう記事が。
http://social.msdn.microsoft.com/Forums/en-CA/vcsharp2008prerelease/thread/33febac0-4073-4d49-8b68-db0ca1255cd2

私の場合逆にVisual Studio 10.0フォルダのdllに変更したら直ったようなのですが。

ちなみに対象のフレームワークが.Net Framework 3.5用(←4.0ではなくて)のプロジェクトをさわっていたので、
そのためにUnitTestFrameworkのdllも古いのが読まれてしまったのかもしれません。。

2009年10月6日火曜日

WPF UIフレームワークのクラス階層図

初歩的なことなのでないのかもしれないけど、
UIフレームワークの全体を把握しやすい図があまりなかった気がする。

この下の方のやつが一目でわかりやすいかなと思う。
クラス階層図

2009年10月2日金曜日

SortDescriptionのXAML記述でひっかかった話

XAMLで書いてたら名前空間ComponentModelにSortDescriptionなんてないよ!ってエラーが出てハマッた。
XAMLで
xmlns:compModel="clr-namespace:System.ComponentModel;assembly=System"
と宣言していたのが間違いで、この場合は
xmlns:compModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
でした。アセンブリごとに定義しないといけないのね。。
普段あんまり意識してなかったので気づきませんでした。。

2009年10月1日木曜日

NUnitのException

ExceptionはAssert.CatchやAssert.Throwsなどで
Assert.Catch<InvalidOperationException>(()=>{a.func();}, "must throw exception");
のような形でテストできるみたい。
でもNUnitについてくるGUI使うときはこれでもいいけど、
前の日記のようにVisual Studioでやっていると、そこで実行が終わってしまう。

これをやろうとするとやっぱり
try {
   a.func();
   Assert.Fail("must throw exception");
} catch (InvalidOperationException) {
   //OK
}
のようにしないといけないのかな?

2009年9月30日水曜日

Express Editionでのnunit test

ここの情報がすごく参考になりました。
NUnitのコードをデバッグ実行する方法。

http://dora.bk.tsukuba.ac.jp/~takeuchi/index.php?%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%2F%A3%C3%A1%F4%2FExpress%20Edition%20%A4%C7%A4%CE%A5%C6%A5%B9%A5%C8%B6%EE%C6%B0%B7%BF%B3%AB%C8%AF

TestDrivenってなんで動かないんだろうと思ったら
普通にインストールした場合、Express Editionじゃ無理なんですね。。

ちなみに、上記の通りやろうとして、nunit.addinを探してしまった。
nunitのとこじゃなくて、TestDrivenの方に入っていました。

delegateをいっぱい書くのがめんどくさいと思ってたら

Action<>とかFunc<>とかあるんですね。
他人のサンプルでAction<>を見て、これなに??と思ったけど、
delegateの型定義して、そのインスタンスを作成して、
というめんどくさかった作業がこれらで不要になるようですね。
戻り値なしがAction<>で戻り値ありがFunc<>みたいです。
サンプルは探せばすぐあるので省略。
これとかLINQとか使うとすごく楽になりますね-。
なれるまで読むのが大変だけど。。

2009年9月29日火曜日

ObservableCollectionにはAddRangeがない

たくさんのアイテムを一度に追加したいときに、
普通にAddすると1個ごとに通知が行きそうだけど
AddRangeがないのでどうしたらいいのかな?
自分で通知を止める仕組みを入れる必要があるのかな?
と思っていたら、以下の記事を見つけた。

http://blogs.microsoft.co.il/blogs/tamir/archive/2008/05/13/how-to-addrange-removerange-in-silverlight-observablecollection-lt-t-gt.aspx

書かれているソースコードは自分がやろうと思っていたこととほぼ同じなんだけど、
簡単に書くと、少ないうちは効果あるけど、数が多くなると逆に遅くなるよってことらしい。

遅くなる原因がこの説明だけだといまいち理解できなかったけど、
とりあえず、今はパフォーマンスで困ってないので、普通にAddで行くことにします。

P.S.
Resetのあたりを工夫するとどうにかできないかなーと思ったけど、
それはまた時間ができたときに。

2009年9月28日月曜日

フォーカス時の点線をなくす

WPFのアイテムで、フォーカスを取得したときに点線で囲まれるときがあるんですけど、
ビジュアル的にこれをやめたくて、
ここで紹介されているやり方で解決しました。
FocusVisualStyle="{x:Null}"でいいようです。

2009年9月27日日曜日

XMLのシリアライズでちょっとハマッタ

ここを参考にさせてもらってファイルにXML形式で保存しようとしたら、
"保護レベルの設定が原因で '(クラス名)' にアクセスできません。パブリックの型のみ処理できます。"
という例外が出た。
フィールドとプロパティを全部publicに直したり
[XmlIgnoreAttribute]
を付けたりしたのに解決しない!!

と思ったら、Classがpublicになっていないというオチでした。

2009年9月26日土曜日

ウィンドウの半透明化

ここを参考にさせてもらいながら半透明にしようとしてたけど、うまくいかなかった。
Backgroundの指定は普通にして、
Opacity="0.2"
の指定をするとうまく半透明にできた。
例のまま作らずに、いきなり自分のアプリに適用させようとしてたから
どこか抜けていたのかもしれないけど。

ついでに、
Background="Transparent"
と完璧な透過にしたら、透過の部分がクリックできないもんだいも
この方法で解決した。