Hatena::ブログ(Diary)

周回遅れのブルース

2017-02-18 WPF FAQ

Q110. XamDataGrid でユーザーが設定したレイアウトを保存したい(其の参)

| 15:14 | Q110. XamDataGrid でユーザーが設定したレイアウトを保存したい(其の参)を含むブックマーク

A.以前、XamDataGrid でユーザーが操作した列の移動や並び替え、グループ化やソートを次回起動時用に保存したい場合、SaveCustomizations メソッドやLoadCustomizations メソッドを使えば、レイアウトの保存・読み込みが可能だという記事を公開しました。

関連記事:Q110. XamDataGrid でユーザーが設定したレイアウトを保存したい


しかし記事の最後に書いたとおり、ClearCustomizations メソッドでフィールドを初期状態に戻そうとすると

  • フィールドの表示状態を初期化できない
  • フィールドの固定がリセットされてしまう

という問題が発生するため、昨日のエントリでは、その対処としてコンストラクタでフィールドの状態を保存し、ClearCustomizationsメソッド実行後、LoadCustomizations メソッドで表示と固定列を初期化する方法を紹介しました。以下、その対処法の記事になります。


関連記事:Q110. XamDataGrid でユーザーが設定したレイアウトを保存したい(其の弐)


カスタムXamDataGrid

上記で一見解決できたように思えましたが、複雑なUIに配置されたグリッドや、TabItem に配置され起動時に非表示になってるグリッドは、コンストラクタや 画面のContentRendered イベント、いや XamDataGrid のOnRender でもフィールドが生成されてない場合があり、列情報を取得できないことがあることが判りました。

結局、DataPresenterBase.FieldLayoutInitialized イベントの通知後でないと、フィールドの初期状態を正確に取得することはできない模様です。

そこで Window のコードビハインドでいちいちイベント書くのも煩わしいため、XamDataGrid をカスタマイズした方が早いという結論に達しました。それがこちら。


コントロールの継承って好きじゃないですが、今回のケースでは止むを得ません。以上、何かの参考になりましたら幸いです。



WPF FAQ の目次に戻る

 

2017-02-17 WPF FAQ

Q110. XamDataGrid でユーザーが設定したレイアウトを保存したい(其の弐)

| 13:14 | Q110. XamDataGrid でユーザーが設定したレイアウトを保存したい(其の弐)を含むブックマーク

A.以前、XamDataGrid でユーザーが操作した列の移動や並び替え、グループ化やソートを次回起動時用に保存したい場合、XamDataGrid.SaveCustomizations メソッドやXamDataGrid.LoadCustomizations メソッドを使えば、レイアウトの保存・読み込みが可能だという記事を公開しました。

関連記事:Q110. XamDataGrid でユーザーが設定したレイアウトを保存したい


しかしこれ、ひとつ問題がありまして、記事の最後に書きましたが

なお上記一連のメソッドの問題点ですが、FieldLayoutSettings で HeaderPrefixAreaDisplayMode プロパティを FieldChooserButton に設定しフィールドの表示項目を選択できるようにした場合、フィールドの表示/非表示の設定を保存したり、非表示にしたフィールドを ClearCustomizations メソッドで復帰することはできません。現状、表示状態の保存は独自に実装するしかないので、この辺りもう少し何とかして欲しいところです。

また、ClearCustomizations メソッドで FieldPosition を初期化すると、FixedLocation=FixedToNearEdge にしたフィールドが FixedLocation=None になってしまうのも問題です。

という悩ましい問題が存在します。


これ、いったいどういう処理を行ってるのか、幸い Infragistics WPFソースコードが公開されてる*1ので読んでみました。DataPresenterBase.ClearCustomizations → CustomizationsManager.ClearCustomizations → FieldLayout.ClearCustomizations と遡ってコードを追ってくと、大元の FieldLayout.ClearCustomizations で Visiblity プロパティを初期化してないため、どうにもならんという結論がでました。*2

だめだこりゃ\(^o^)/*3


FieldChooser 対応版

そこで私は考えた。画面初期化時にField の情報をメンバ変数に保持し、いったん LoadCustomizations で読み込んでから ClearCustomizations メソッドを実行すればいいのではと・・・で、以下サンプルです。

f:id:hilapon:20170217131400p:image:w400


まずビュー。


お次はコードビハインドです。Reset_Click メソッドに注目してください。


LoadCustomizations で十分では?と思う向きもおられるかもしれません。しかし列の移動や段組が初期化されないため、まず全プロパティを初期化した後、表示と列固定を初期状態に戻します。これで前回の宿題は解決しましたが、これに気づくまで3年かかりましたw



WPF FAQ の目次に戻る

*1:ライセンス購入すればインフラさんのサイトからダウンロードできます

*2:カスタマイズしてもいいが、めんどくさすぎる

*3:列の仮想化という問題もあり、実装がややこし過ぎたのかもしれんが

2017-02-16 WPF FAQ

Q125. コントロールの Visiblity プロパティに bool 値をバインドしたい

| 13:32 | Q125. コントロールの Visiblity プロパティに bool 値をバインドしたいを含むブックマーク

A.いまさら感がひしひし漂うネタですが、まあコンセプトが周回遅れブログのため、その辺りは気にせずスルーでお願いできればと思います。

コントロールの Visiblity プロパティに、ビューモデル側の bool 型プロパティをバインドさせたいシーンは多いと思います。Visiblity プロパティの型は System.Windows.Visibilityのため、bool と互換性はありません。こういう具合に型が異なるもの同士をバインドしたいときに用意するのがいわゆるコンバーターです。

参考記事:WPFのデータ変換


殆どのケースでは、上の記事のように自作しなければならないのですが、Visibility と bool 値のバインドでは、標準で用意されているコンバーターが存在します。それが BooleanToVisibilityConverter です。


サンプルコード

以下、簡単なサンプルを考えてみました。チェックボックスをONにすると、テキストを表示するプログラムです。

f:id:hilapon:20170216131431p:image


まずビューモデルです。ちなみにMVVMフレームワークLivet を使ってます。


お次はビュー。TextBlock の Visibility プロパティとビューモデルの IsChecked プロパティを BooleanToVisibilityConverter を使ってバインドしてます。


上のコードでは少々XAMLが冗長になってしまうので、通常コンバーターを使う場合、リソースに定義して使いまわします。以下、リソースを使ったサンプルです。アプリケーション全体で使用するなら App.xaml (VB なら Application.xaml) に定義しておくといいでしょう。


System.Windows.Controls 空間には他にも幾つかコンバーターが用意されてますが、使いどころが微妙なコンバーターばかりですね。よくありがちな数値とテキストの変換などは標準のコンバーターが用意されてないので、自前のコンバーターを用意する必要があります。


WPF FAQ の目次に戻る


 

2017-02-10 WPF FAQ

Q124. XamDataGrid で絞り込み表示されてるレコードのみ抽出する

| 18:19 | Q124. XamDataGrid で絞り込み表示されてるレコードのみ抽出するを含むブックマーク

A.昨日の記事に引き続き、またまた XamDataGrid ネタです。

XamDataGrid で、フィルターで絞り込まれているレコードのみを抽出には、各レコードの IsDataRecord プロパティで判定し抽出する必要があります。


以下、サンプルコートです。


前回もそうでしたが、このサンプルでもメソッドのパラメータに XamDataGrid ではなく、XamDataGrid の上位クラスである DataPresenterBase を渡しています。実は DataPresenterBase クラスで XamDataGrid が提供する殆どの機能*1が定義されているためです。


WPF FAQ の目次に戻る


 

*1:プロパティやメソッド等

2017-02-09 WPF FAQ

Q123. XamDataGrid で表示されている内容をそのまま EXCEL に出力したい

| 11:28 | Q123. XamDataGrid で表示されている内容をそのまま EXCEL に出力したいを含むブックマーク

A.くそ忙しかったため、かなりご無沙汰しておりましたが、久々の XamDataGrid ネタです。

XamDataGrid で表示されている内容を Excel に出力したい場合、DataPresenterExcelExporter クラスの Export もしくは ExportAsync メソッドを使うといいです。このメソッドの嬉しいところは、列の移動や並び替え、列の表示/非表示等、表示されてる状態のまま、Excel に出力してくれます。


以下、スニペットです。


参照設定は、通常のデータプレゼンター関連 (InfragisticsWPF4 ほにゃらら) に加え、以下の二つのアセンブリが必要になります。

InfragisticsWPF4.DataPresenter.ExcelExporter.v16.2

InfragisticsWPF4.Documents.Excel.v16.2


WPFについては、ここ数年かなり貯め込んだネタがあるので、随時公開していきたいと思います。しかしこれってホントは FAQ じゃなく TIPS というべきなんですよね。そのうち機会見て、今までの記事を再構築したいと考えてます。でもいつになるやら・・・


WPF FAQ の目次に戻る