質問

WPFのデータバインディングに問題があります。

値コンバーターを使用して、notifyOntargetUpdated = trueプロパティをtrueに設定しようとすると、次のメッセージでxamlparseexceptionを取得します。

'System.Windows.Data.BindingExpression'値は、「オブジェクト」のプロパティ「contenu」に割り当てることはできません。値はヌルにすることはできません。パラメーター名:オブジェクトのtexttoformatエラー 'system.windows.data.binding' in markup file 'view.usercontrols; component/saletotal.xaml' line 363 position 95。

バインディングはかなり標準です:

<my:ShadowedText Contenu="{Binding Path=Total,
                                   Converter={StaticResource CurrencyToStringConverter},
                                   NotifyOnTargetUpdated=True}"
                 TargetUpdated="MontantTotal_TargetUpdated">
</my:ShadowedText>

(簡潔にするために削除されたスタイリングプロパティ)

コンバーターはリソースに存在し、NotifyOntargetUpdated = trueが削除されると正しく機能します。同様に、TargetUpdatedイベントは呼び出され、正しく実装され、コンバーターが削除されたときに機能します。

ノート: このバインディングはControlTemplateで定義されていますが、それが問題に関連しているとは思いません。

誰かが私に何が起こっているのかを説明できますか?私はバインディングを間違って定義していますか?これらの機能は相互に排他的です(この場合、なぜそうなのか説明していただけますか)?

前もって感謝します。

より詳しい情報: これがターゲットアップデートのハンドラーのコンテンツです:

private void MontantTotal_TargetUpdated(object sender, DataTransferEventArgs e)
{
    ShadowedText textBlock = (ShadowedText)e.TargetObject;
    double textSize = textBlock.Taille;
    double delta = 5;
    double defaultTaille = 56;
    double maxWidth = textBlock.MaxWidth;
    while (true)
    {
        FormattedText newFormat = new FormattedText(textBlock.Contenu,
                                                    CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                                                    new Typeface("Calibri"), textSize,
                                                    (SolidColorBrush) Resources["RougeVif"]);
        if (newFormat.Width < textBlock.MaxWidth && textSize <= defaultTaille)
        {
            if ((Math.Round(newFormat.Width) + delta) >= maxWidth || textSize == defaultTaille)
            {
                break;
            }
            textSize++;
        }
        else
        {
            if ((Math.Round(newFormat.Width) - delta) <= maxWidth && textSize <= defaultTaille)
            {
                break;
            }
            textSize--;
        }
    }

    textBlock.Taille = textSize;
}

ハンドラーの役割は、コンテンツの長さに基づいてコントロールをサイズ変更することです。それは非常に醜いですが、リファクタリングする前に機能的な部分を動作させたいと思っています。

役に立ちましたか?

解決

このコントロールの初期化中にこのエラーが発生していることを意味するXamlParseExceptionを取得している場合。

NotifyOnTargetUpdated=True 指定された、ターゲットアップデートされたイベントは、初期化のコンポーネントコール内で提起されています。この時点で、あなたがデータコンテキストを持っていることは信じられないほど疑わしいので、バインディングはnullと評価されます。通常、問題はありませんが、プロパティが更新されたときにイベントを提起することを要求しています。

だからそれはあなたのイベントハンドラーをヌルで叩いています textBlock.Contenu 値、FormattedTextの最初のパラメーターに渡す textToFormat)そして、それは引数項目を投げています。

いくつかの防御プログラミングを練習し、あなたをチェックしてください textBlock.Contenu コードを実行する前のnullの値。

将来の参照のための2つのヒント:

1)例外を受信するときは、Innerexceptionを含むスタックトレース全体を貼り付けます(したがって、例外を呼び出してください)。多くの場合、あなたはそれがどこで起こっているかを見るでしょう。そうでない場合、ここにいる誰かが、あなたが答えを得たよりもはるかに速くそれがどこで起こっているのかを見るでしょう。

2)例外を受信し、それがどこから投げられているのかわからない場合(そして、あなたは明らかにそうではないか、それがあなたのコードにあるのを見たでしょう)、Visual Studioにあらゆる例外を壊すように強制します。http://msdn.microsoft.com/en-us/library/d14azbfh(vs.80).aspx

(設定に応じて、参照されるメニュー項目はそこにある場合とそうでない場合があります。CTRL+ALT+Eを使用して、例外ダイアログを開くこともできます。)

このセットを使用すると、デバッガーは例外をスローするコードの正確な行で停止します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top