2011-08-24 63 views
2

例如,讓我們來編程綁定:如果我將一個控件綁定到另一個控件,並且其中一個控件死亡,綁定會發生什麼?

Binding binding = new Binding("MyProperty"); 
binding.Converter = new BooleanToVisibilityConverter(); 
binding.Source = myWindow.myObject 

myButton.SetBinding(Button.VisibilityProperty, binding); 

如果mywindow的死了,被垃圾回收,會發生什麼......我是負責釋放的結合爲好,還是它知道如何做到這一點本身?

+2

我不認爲其他控制可以得到GC'd現在還有通過結合對它的引用。 – msarchet

+0

請不要在標題中使用諸如「C#:」之類的內容。這就是標籤的用途。 –

+0

凱,我會停止這樣做...好點 – foreyez

回答

0

根據MSDN:

In C# garbage collection is handled by the comman language runtime (CLR) which is similar the Java's JVM. Garbage collecter periodically checks the memory heap for any unreferenced objects, and releases the resources held by these objects.

因此,在你的例子mywindow的對象不能被垃圾收集,因爲存在從綁定對象到mywindow的一個引用。

1

我認爲它會被垃圾收集,作爲

The object is alive until the garbage collector finds out that the object is no longer reachable from a strong root reference via a path of strong references

從這裏Managing object lifetime

你仍然有一個指針binding.**Source**它。

2

對於綁定,這不是真的,即使您將Source用於Binding,也不會有內存泄漏。

爲了驗證這一點

  • XAML創建
  • 一個StackPanel,一個TextBox(TB1)和兩個Buttons在後面的代碼創建一個新的TextBox(TB2)
  • 坐落在TB1一個BindingSource設置爲tb2
  • 在tb2上創建一個WeakReference(如果我們有泄漏,則不應該GC'd)
  • 添加TB2爲StackPanel
  • 運行程序並驗證綁定的工作
  • 單擊刪除
  • 點擊是還活着嗎?

返回false,源TextBox(TB2)已被垃圾回收,所以我們都沒有內存泄漏

編輯:您也可以從XAML中移動第一TextBox的創建到後面的代碼和使用兩個WeakReferences(每個TextBox一個),並驗證兩個文本框是否都正確地GC'd,你會發現這是真的。

的XAML

<StackPanel Name="stackPanel"> 
    <TextBox Name="textBox"/> 
    <Button Name="removeButton" Content="Remove" Click="removeButton_Click"/> 
    <Button Name="isAliveButton" Content="Is Alive?" Click="isAliveButton_Click"/> 
</StackPanel> 

代碼隱藏

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     TextBox toBeGCdTextBox = new TextBox(); 
     stackPanel.Children.Add(toBeGCdTextBox); 
     Binding textBinding = new Binding 
     { 
      Path = new PropertyPath("Text"), 
      Source = toBeGCdTextBox 
     }; 
     textBox.SetBinding(TextBox.TextProperty, textBinding); 
     _weak = new WeakReference(toBeGCdTextBox); 
    } 
    private WeakReference _weak; 
    private void isAliveButton_Click(object sender, RoutedEventArgs e) 
    { 
     GC.Collect(); 
     MessageBox.Show(_weak.IsAlive.ToString()); 
    } 

    private void removeButton_Click(object sender, RoutedEventArgs e) 
    { 
     Debug.Assert(_weak.Target == stackPanel.Children[3]); 
     stackPanel.Children.Remove(stackPanel.Children[3]); 
    } 
} 
+0

有趣......雖然你提到它在後臺返回某種警告。我打算創建和銷燬很多這些窗口,所以我不確定綁定是否是最佳實踐。 (是的,我需要綁定主窗口上的屬性和窗口上的屬性多次打開和關閉),也許我會做某種事件觸發,而不是......我不確定這是否是最佳實踐即使沒有內存問題 – foreyez

+0

我刪除了該評論,因爲它不是真的。我剛剛嘗試過,並且當源看到存在時,您不會在「輸出」窗口中看到任何警告。我不確定這個的原因,但是如果你在FindAncestor中使用無效的'RelativeSource','DataContext'上的無效屬性等,它們就會出現。它看起來像這樣:** System.Windows.Data Error :4:無法找到與參考綁定的源代碼... ** –

+0

因此情節變厚了......我需要我的主窗口的用戶界面對在子窗口中更改的屬性做出反應......您認爲綁定是去這裏的方式或者可能是其他類型的交流?你似乎證明綁定沒有很多缺點,所以我有點混淆 – foreyez

相關問題