2010-06-16 51 views
2

我有一個數據綁定在WPF中的問題。WPF Converter和NotifyOnTargetUpdated在綁定中獨佔?

當我嘗試使用值轉換器,並設置NotifyOnTargetUpdated = true屬性爲True,我得到以下消息的XamlParseException:

「System.Windows.Data.BindingExpression」 值不能分配給屬性 'Contenu'對象 'View.UserControls.ShadowedText'。 值不能爲空。參數名稱:在 標記文件 對象 'System.Windows.Data.Binding' textToFormat錯誤 'View.UserControls;組件/ saletotal.xaml' 線363的位置95

的結合是相當標準:

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

(造型屬性爲了簡潔移除)

該轉換器中的資源存在,並且工作正常時NotifyOnTargetUpdated = Tr的你被刪除。同樣,TargetUpdated事件被調用並正確實現,並在轉換器被移除時起作用。

注意:該綁定在ControlTemplate中定義,但我認爲這與該問題無關。

任何人都可以解釋我發生了什麼?我是否定義了綁定錯誤?這些功能是否相互排斥(在這種情況下,你能解釋爲什麼它是這樣)?

在此先感謝。

更多信息:這裏是TargetUpdated處理程序的內容:

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; 
} 

處理程序的作用是調整基於內容的長度控制。這是相當醜陋的,但我想在重構之前讓功能部分工作。

+0

你在做什麼特別的TargetUpdated事件處理程序? – 2010-06-16 12:13:38

+0

我不知道它是否只是一個錯字,但你在綁定中缺少一個逗號。它應該看起來像這樣:{Binding Path = Total,Converter = {StaticResource CurrencyToStringConverter},NotifyOnTargetUpdated = True} – 2010-06-16 12:34:20

+0

這是一個拼寫錯誤,爲了提高可讀性,我在問題中添加了換行符,Converter和NotifyOnTargetUpdated部分之間存在昏迷在真正的源代碼中。編輯問題來解決這個問題。 – 2010-06-16 12:39:33

回答

2

如果您得到一個XamlParseException,這意味着此控件初始化期間發生此錯誤。

由於指定了NotifyOnTargetUpdated=True,因此在InitializeComponent調用中引發了TargetUpdated事件。在這一點上,令人懷疑你有一個DataContext,所以綁定將評估爲null。通常情況下,沒有問題,但是您要求在更新媒體資源時提出事件。

因此,它的值爲空textBlock.Contenu,因此它將事件處理程序傳遞給FormattedText的第一個參數(名爲textToFormat),並且它將引發ArgumentNullException。

練習一些防禦性編程,並在運行代碼之前檢查空值textBlock.Contenu爲null。

以供將來參考

兩個尖端:

1)當接收到一個異常,粘貼整個堆棧跟蹤,包括的InnerException(這麼稱呼Exception.ToString)。通常情況下,你會看到它發生的地方。如果不是這樣,那麼這裏的某個人會比你得到答案的時間快得多。

2)當接收到一個異常,並且您不知道它從哪裏拋出(並且您顯然沒有,或者您已經看到它在您的代碼中)時,強制Visual Studio打破所有異常。 http://msdn.microsoft.com/en-us/library/d14azbfh(VS.80).aspx

(請注意,根據您的設置,它們引用可能會或可能不會在那裏,您還可以使用CTRL + ALT + E打開例外對話框中的菜單項。)

有了這一套,調試器將停止在拋出Exception的代碼的確切行上。

+0

謝謝,那正是問題所在。在控制的初始化期間,我根本沒有期待被召喚。 – 2010-06-16 13:41:55