2012-02-24 54 views
12

我正在使用WPF SQL Connection User Control。我有一個問題,它拋出一個StackOverflowException每當我有一個選項卡(AvalonDock DocumentTab)已打開,關閉,然後再次打開。使用默認值拋出的依賴屬性StackOverflowException

我已經搞亂了Jake的基本實現,以更好地適合我的應用程序,但它本質上是相同的。我添加了一個禁用數據庫選擇的屬性。

我放在控制到我的應用程序是這樣的:

<controls:SqlConnectionStringBuilder 
     Grid.Row="2" 
     Margin="0,10,0,0" 
     ConnectionString="{Binding ElementName=listBoxClients, 
            Path=SelectedItem.ConnectionString, 
            UpdateSourceTrigger=PropertyChanged}" 
     Header="Connection String" 
     RequireDatabase="True" /> 

爲了解決這個問題,我已經做了的SqlConnectionStringBuilder的代碼隱藏的一些重構,而這似乎是有問題的代碼:

public static readonly DependencyProperty ConnectionStringProperty = 
    DependencyProperty.Register(
     "ConnectionString", 
     typeof(SqlConnectionString), 
     typeof(SqlConnectionStringBuilder), 
     new FrameworkPropertyMetadata(
      new SqlConnectionString { IntegratedSecurity = true, Pooling = false }, 
      FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 

public SqlConnectionString ConnectionString 
{ 
    get { return (SqlConnectionString)GetValue(ConnectionStringProperty); } 
    set { SetValue(ConnectionStringProperty, value); } 
} 

SqlConnectionString對象進入與其OnPropertyChanged方法無限循環和IntegratedSecurity屬性的標籤的第二開口。當我使ConnectionString屬性不是DependencyProperty時,我不會收到此問題。對我來說,這表示問題是依賴項屬性的默認值。

我在網上查了一下,看看是否有其他人有這個問題,但似乎我可能已經陷入了一片醃製。唯一可以認爲這個問題可能來自的是關於this SO question about dependency properties which was answered as thread safety。我不確定依賴項屬性如何處理它們的默認值,但我可以看到,如果同一對象與OnPropertyChanged事件連接了兩次問題。然而,這也使我相信,如果是這種情況,這個問題會在某個地方被注意到!

有什麼想法?

附加信息
我從依賴屬性(其設置爲空)的登記刪除的默認值。這可以防止問題發生。此解決方案唯一的缺點是UI處於null狀態,沒有默認選擇。不過,我想通過解決這個問題來防止這種情況發生。

+1

不確定問題是什麼,但不應該將默認值設置爲可變引用類型的實例,因爲**它將由您的類的所有實例**共享!如果可以,請改爲將SqlConnectionString設爲值類型。 *編輯:其實你不能,因爲這個類似乎沒有在你自己的代碼中...* – 2012-02-24 15:55:17

+0

@ThomasLevesque我認爲你用「**它將被所有實例**共享」來釘住它。我不知道它是如何進入屬性更改的無限循環,但它與作爲初始化器傳遞的值有關,我可以看到這是一個問題。 – 2012-02-24 16:24:59

回答

0

也許,在二傳手加入

if (value != GetValue(ConnectionStringProperty)) 

將停止。

2

每次標籤關閉處理它們時,是否註冊新的依賴項屬性?我相當肯定,如果它的引用已被處置,你不能重用相同的依賴項屬性註冊。一旦你關閉標籤,垃圾收集器將嘗試吃掉你的「ConnectionString」對象。它將在標籤丟失範圍時處置所有子變量,即使它們是靜態只讀。

1

在那個無限循環中,誰正在對IntegratedProcurity屬性進行賦值以響應OnPropertyChanged?如果你發現那是誰,這是你答案的關鍵。