SSブログ

【Note】WPF 実行時に XamlParseException、対象が App.xaml 追加の Resources.resx [WPF]

WPF でリソース ファイル Resources.resx を使用すると、以下のような実行時例外がスローされることがあります。

型 'System.Windows.Markup.XamlParseException' の初回例外が PresentationFramework.dll で発生しました
追加情報:'一致するコンストラクターが型 '<リソース クラス名>' に見つかりません。この型は、引数または FactoryMethod ディレクティブを使用して構築できます。' 行番号 '<行>'、行位置 '<列>'。


使用方法が最小限であると、心当たりがなくて詰んでしまいます。

<Application x:Class="<クラス名>"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:properties="clr-namespace:<プロパティ名前空間>"
             StartupUri="<開始画面 xaml>">
    <Application.Resources>
        <properties:Resources x:Key="resources" />
    </Application.Resources>
</Application>


この場合、実行時例外のメッセージから見て、引数なしのコンストラクターが単純に見つかっていないようです。

リソース ファイル Resources.resx.cs の自動生成コードでは、アクセス修飾子が public でも、必ず internal のデフォルト コンストラクターが作成されます。

internal Resources() {
}


ビルドの直前に、これを手で public に書き換えてしまいましょう。

public Resources() {
}


こうすると、実行時例外がスローされなくなります。

なお、このコンストラクターは、リソース デザイナーで Resources.resx を保存(書き換えではない)すると、自動的に修飾子が internal に戻ります。

一旦 public で実行できるようになったプロジェクトは、以後 internal に戻っても、クリーンしない限り冒頭の実行時例外を回避することができます(リビルドでも大丈夫)。

プロジェクトをクリーンしてしまったら、上記の手順でもう一度コンストラクターを一時的に public に書き換えてビルドし、改めて internal に戻しておきます。

現象から見て、リソース ファイルのソースコード自動生成部と、XAML パース部との間で、リソース クラスのコンストラクター修飾子に関連する不整合があるような気がします。 

いずれ詳しく追跡して、例外をスローする原因を含む中途生成ファイルの特定と、こうなってしまう根本的な原因を解明してみようと思います。 


【Tips】iPad で select.onchange 中に alert や confirm でフリーズする問題を回避 [iOS]

iOS 7.0.2 に見られた厄介な不具合の回避方法です。

iOS 7.0.2 Safari Mobile では、select タグの onchange イベントハンドラー内で JavaScript の alert や confirm を実行すると、ユーザーが応答した瞬間にフリーズします。

この問題を回避するには、alert や confirm を select.onchange イベントの期間の後で実行します。

まず select.onchange イベントハンドラーでタイマーだけを仕掛けてイベントから抜けておき、タイマーイベントで alert や confirm を実行したい処理を起動するようにします。

$(function() {
    $("select[id='id']").bind("change", null, function() {
        setTimeout(function() {
            if (confirm(message)) {
                ...
            }
            else {
                ...
            }
        }, 100);
    });
});


タイマーイベントが発生する前のなんらかのコンテキストをタイマーイベントハンドラー内の処理で取得したい場合には、クロージャを活用すると便利です。

なお、この不具合は iOS 7.0.3 でフィックスされたそうです。

 


【Tips】iPad でポップアップの window.onunload 代替え処理を実装 [iOS]

個人的には Web システムで window クローズ系イベントをトリガーとする処理は実装しない方がよいと思いますが、仕事上で改修の必要に迫られたので調べてみました。

iPad に搭載されている Safari Mobile では、window.onload や window.onunload イベントが発生しません。

ロード時には代替えイベントがあるし、ポップアップ(window.open で開いたウィンドウ)でなければアンロード時の代替え方法もあるんだけど、ポップアップのアンロードではちょっとハマりかけました。

window.onpagehide は来るタイミングが遅いし、body.onunload は来ませんでした。

JavaScript でクローズ処理が書けるなら、以下の方法が使えるようです。

$(window).bind("pagehide", null, function() { /* イベント処理 */ });
   ・・・
window.open("about:blank", "_self").close();


ブランクで window のアンロードを発生させることで、期待通りのタイミングで onpagehide イベントを発生させる…という流れですね。

しかし残念なことに、Safari Mobile タブ上の × ボタンでクローズされると、この実装は役に立ちません。 


【Tips】jQueryセレクターで複数のセレクター属性を指定する [jQuery]

ネット上であんまり情報を見かけたことがないので、Tips として掲載します。

jQuery セレクターでは、セレクターに抽出させたい情報を文字列で記述しますが、この際に複数のセレクター属性を設定できます。

以下の例では、class 属性が "myclass" のチェックボックスをすべてチェック状態にします。

$("input[type='checkbox'][class='myclass']").attr("checked", "checked");

マークアップが煩雑化している古い Web システムの保守をするときに、重宝しています。


この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。