C# 如果我将一个控件绑定到另一个控件,并且其中一个控件死亡,那么绑定会发生什么情况? 例如,让我们采用一个程序绑定: Binding binding = new Binding("MyProperty"); binding.Converter = new BooleanToVisibilityConverter(); binding.Source = myWindow.myObject myButton.SetBinding(Button.VisibilityProperty, binding);

C# 如果我将一个控件绑定到另一个控件,并且其中一个控件死亡,那么绑定会发生什么情况? 例如,让我们采用一个程序绑定: Binding binding = new Binding("MyProperty"); binding.Converter = new BooleanToVisibilityConverter(); binding.Source = myWindow.myObject myButton.SetBinding(Button.VisibilityProperty, binding);,c#,wpf,data-binding,memory-leaks,garbage-collection,C#,Wpf,Data Binding,Memory Leaks,Garbage Collection,如果myWindow死机并被回收垃圾会发生什么。。。我是否也负责释放绑定,或者它自己知道如何释放绑定?根据MSDN: 在C#中,垃圾收集由comman语言运行库处理 (CLR)类似于Java的JVM。垃圾收集器 检查内存堆中是否存在任何未引用的对象,以及 释放这些对象所持有的资源 因此,在您的示例中,myWindow对象不能被垃圾收集,因为存在从绑定对象到myWindow的引用。我认为它不会被垃圾收集,因为 在垃圾收集器发现 对象不再可以通过路径从强根引用访问 强引用 从这里 您仍然有一个指向它

如果myWindow死机并被回收垃圾会发生什么。。。我是否也负责释放绑定,或者它自己知道如何释放绑定?

根据MSDN:

在C#中,垃圾收集由comman语言运行库处理 (CLR)类似于Java的JVM。垃圾收集器 检查内存堆中是否存在任何未引用的对象,以及 释放这些对象所持有的资源

因此,在您的示例中,myWindow对象不能被垃圾收集,因为存在从绑定对象到myWindow的引用。

我认为它不会被垃圾收集,因为

在垃圾收集器发现 对象不再可以通过路径从强根引用访问 强引用

从这里


您仍然有一个指向它的指针
绑定。**Source**

这对于绑定是不正确的,即使您对
绑定使用
Source
,也不会有内存泄漏

为了验证这一点

  • 在Xaml中创建一个
    堆栈面板
    、一个
    文本框
    (tb1)和两个
    按钮
  • 在代码隐藏中创建一个新的
    文本框
    (tb2)
  • 在tb1上设置
    绑定
    ,并将
    源设置为tb2
  • 在tb2上创建一个
    WeakReference
    (如果我们有泄漏,不应该使用GC)
  • 将tb2添加到
    StackPanel
  • 运行程序并验证绑定是否有效
  • 单击删除
  • Click还活着吗
它返回false,源
文本框(tb2)已被垃圾收集,因此没有内存泄漏

编辑:您还可以将第一个
TextBox
的创建从Xaml移动到code behind,并使用两个
weakreference
(每个
TextBox
)并验证两个文本框是否正确地获得GC,您将看到这是正确的

Xaml


我不认为另一个控件可以得到GC'd,因为仍然有一个通过绑定对它的引用。请不要在标题中使用类似“C:”。这就是标签的作用。凯,我不会再这么做了。。。好的,视情况而定。。窗户的预期寿命是多少?不是很长,这是针对许多被创建和破坏的有趣窗户。。。虽然你提到过,但它会在后台返回某种警告。我打算创建和销毁很多这样的窗口,所以我不确定绑定是否是这里的最佳实践。(是的,我需要在主窗口上的属性和多次打开和关闭的窗口上的属性之间进行绑定),也许我会执行某种类型的事件触发。。。我不确定这是否是最好的做法,即使没有内存问题。我删除了那个评论,因为它不是真的。我刚刚尝试过,当源代码看到存在时,输出窗口中没有任何警告。我不确定出现这种情况的原因,因为如果将无效的
相对资源
与FindAncestor一起使用,
数据上下文
上的无效属性等一起使用,它们就会出现。它看起来像这样:System.Windows.Data错误:4:找不到与引用绑定的源…因此绘图变厚。。。我需要主窗口的ui对子窗口中更改的属性作出反应。。。您认为绑定是一种方式,还是其他类型的通信?你似乎证明了绑定没有太多的缺点,所以我有点混淆了。我通常选择绑定到ViewModels,所以我不确定。我从来没有想过这种可能性。但是,只要在窗口之间设置新绑定(当一个窗口死掉时,无论如何都没有任何绑定对象),将多个窗口绑定到一个公共viewmodel时,它应该可以+1工作。在子窗口中定义子窗口绑定(最好是在XAML中,以确保不会在代码中引入任何古怪的内容),并在收集子窗口时让WPF自动清理。
<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]);
    }
}