WPFのListViewを使ってリッチなカスタムリストを作成したとき、クリックしたときに背景色が変わるのを解除したくなります。せっかく綺麗なデザインにしたのにクリックした瞬間に選択色がついて台無しに。しかし残念ながらListViewのプロパティ1つをFalseにすれば済むような話ではありませんでした。
ListViewを選択したときのハイライト
こんなListViewがあったとします。ここで例えば「0005」をクリックしてみます。
WPFのListViewを使ってリッチなカスタムリストを作成したとき、クリックしたときに背景色が変わるのを解除したくなります。せっかく綺麗なデザインにしたのにクリックした瞬間に選択色がついて台無しに。しかし残念ながらListViewのプロパティ1つをFalseにすれば済むような話ではありませんでした。
こんなListViewがあったとします。ここで例えば「0005」をクリックしてみます。
WPFアプリケーション開発において多言語対応というのは悩みの種です。Androidはstrings.xmlでテキストは管理され、各国語のstrings.xmlを作成すればOSが使い分けてくれるのですが、WPFにもそんな便利機能はあるのでしょうか。
どうやらLocBamlツールというものを使う方法がMicrosoftの標準推奨だそうです。が、ググってみれば分かりますが誰も使っていません。MSDNを読んでみても数秒でコレジャナイ感でいっぱいになります。
方法 : アプリケーションをローカライズする
Android Databindingを使用してアプリ開発を行っているのですが、Fragmentを使った画面遷移でアプリクラッシュする問題に直面してしまいました。原因を特定するのに時間を使ってしまったので、記録として残しておきます。
この問題に直面して数日経過してしまったため詳細は記憶が曖昧になってきているのですが、問題はActivityのButtonが押下されたときにFragmentの表示を切り替える場面で発生したと記憶しています。1枚目のFragmentはActivity表示時に一緒に描画されていたのですが、それを2枚目に切り替えようとしたときにクラッシュした感じですかね。クラッシュした箇所はFragmentのonCreateViewの中のLayoutInflater.inflater.inflaterメソッドだったと思います。
public static class ExampleFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.example_fragment, container, false); } }
はい。分かる人は分かると思うのですが、Android DevelopersのFragmentのリファレンスにも記述されている自動生成のコードです(フラグメント | Android Developers)。そして、記憶が曖昧ですが下記のようなエラーメッセージが出てました。
Duplicate ID, tag null, or parent id with another fragment for Fragment.
良く分からないですけど、LayoutInflater.inflater.inflaterメソッドの第一引数であるR.layout.example_fragmentが重複しているようなのです。そんなことってあるんですかね…。対策をググってみると重複しているなら削除してしまえという対処療法は見つかるものの、根本的な解決策は見つからぬまま。うーんどうしたものか。
WPFアプリケーションを実行した時に画面がレンダリングされる前にXamlParseExceptionがスローされてクラッシュすることがあります。この例外はデバッカーで原因位置を特定できない場合があり、初めて見たときは絶望と挫折を経験する人もいるかもしれません。僕もWPFアプリケーション開発初期に調べて時間かかった経験があるので、今までのノウハウをメモとして残しておきます。
WPFアプリケーションにおいてXAMLをロードしてパースするときやXAMLのAPIを使用中に何らかのエラーが発生したときにスローされる例外です。
XamlParseException クラス (System.Windows.Markup)
相変わらず奇妙な機械翻訳でMSDNの説明は分かりにくいですが、XamlParseExceptionという名前から先入観でXAMLに問題があると思ってしまいますが、上記のようにXAMLのAPIの使用中のエラーでもスローされるようで、必ずしもXAMLに問題があるわけではありません。というか、多くの場合はそうでないような…。
不必要になったファイルを削除することになったのですが、ファイルを削除すりだけではディレクトリ(フォルダ)が残ってしまう結果に。アプリケーションを利用すればすりほどディレクトリが無限に増えるのは気持ち悪いので、ファイルが1つも存在しなくなればディレクトリを削除することにしました。
.Net Frameworkではサブディレクトリやファイルが存在しない場合は削除するというオプションは用意されていません。
Directory.Delete("c:/..."); Directory.Delete("c:/...", true);
パスだけの指定の場合はディレクトリの中にファイルやサブディレクトリが存在するとIOExceptionがスローされてしまいます。また第2引数は存在するファイルやサブディレクトリごと削除するフラグなのでtrueにすると、ファイルやサブディレクトリが残っているのに削除してしまいます。falseにするとIOExceptionがスローされるだけです…。
サーバーサイドから公開鍵をPem形式でもらったのですが、クライアントサイドで暗号化しようとすると CryptographicExceptionがスローされてしまう事態に。解決に時間を要したのでメモとして書き残しておきます。
公開鍵を使って暗号化する場合はRSAを使うのでRSACryptoServiceProviderを使用します。当時はPem形式の取り扱いが全然分からなかったので、とりあえずコンバーターサイトでXMLに変換して暗号化を試みていました。
var rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(publicKey); rsa.Encrypt(data, false);
するとRSACryptoServiceProvider.FromXmlStringメソッドがCryptographicExceptionをスローするんですね。秘密鍵だと問題がないのですが、公開鍵だとダメなんです。とても困ったのですが、当時は秘密鍵でしか暗号化しなかったのでとりあえず棚上げ。
WPFにおいてページやウインドウが開かれた時に自動で処理を開始したいときって結構あると思います。しかし意外と最適解が探しても見つからず、苦労したので今までの試行錯誤で得たノウハウを書き残しておきます。
最初にやりがちなのはViewModelのコンストラクタで最初に実行する処理のメソッドを呼んでしまう方法です。
public ViewModel() { Start(); } private void Start() { .... }
これだとインスタンスを作るときにStartメソッドが走るので、Startメソッドが終了するまでインスタンスの生成が終わらず、当然終わるまではViewとのバインディングも実行されないという状況に陥ります。
var ViewModel = new ViewModel();
結果、ページやウインドウが開かれたときに処理は終わってしまっているわけです。ただ、内容によってはそれで表示されて実行されたように見える場合もあるかもしれません。最悪なのはViewからのコマンド待ちなどがある場合で、フリーズしてしまうこともあります。
会社にはRailsエンジニアの方が多いので、技術や仕様がそっちに引っ張られることが多い環境にいます。最近は会社にも馴染んでそうでもなくなってはきましたが。そんな中、通信の暗号化でクライアント側で暗号化するよう要請が。そこで渡されたのがPem形式の鍵。しかし.Net Frameworkはそのままでは使えません。これをXMLにしないと…。でもどうやって?
まず検討したのが、もらった鍵を変換して使う方法。変換して取得したXMLをクライアントで保持すればいいですね。ただ、鍵を得体の知れないサイトに送信するというのは気持ち悪いです。公開鍵ならまだしも、秘密鍵は尚更躊躇しますよねえ。。。
RSA Key Converter - Superdry Developer
福岡県生まれ育ちの男の子です。大学、大学院ともに情報工学と生物学を専攻し、卒業とともに神奈川に移住してきました。神奈川に移住してからは機械メーカーでソフトウェア開発者として産業用ロボットの制御プログラムやそれを作成するCAMを開発していました。開発業務はシステムエンジニアリングがメインでしたが、最後の1年は数十年積み重ねられた負の遺産のリファクタリングを中心としていました。
前述の機会メーカーに4年勤めたあとは、入社時点で社員15名程度のFintechスタートアップにアプリケーションエンジニアとして転職しました。現職ではWindowsタブレットで動作するアプリケーションの開発を行なっています。業務範囲はアーキテクチャ設計からドメイン設計、XAMLのコーディングからビジネスロジックの実装、各種デバイスの制御まで全て行なっています。各種デバイスというのは、サーマルプリンターやバーコードリーダー、クレカリーダーやんNFCリーダーなど多種多様です。入社数ヶ月で前職のコーディング量は超えたと思います(笑)。使用言語はC#で開発環境は.Net Framework, WPF, VIsual Studioです。UWPやXamarinで開発リソース不足の打開を図りたいのですが、先に書いたデバイスがデスクトップアプリにしか対応していない場合も多く、やむを得ずWPFアプリケーションとして開発を続けています。
続きを読む