gpt4 book ai didi

wpf - WPF 控件是否在其绑定(bind)中使用弱事件?

转载 作者:行者123 更新时间:2023-12-03 22:32:02 26 4
gpt4 key购买 nike

当我在 WPF 中使用数据绑定(bind)时,我的目标控件正在监听绑定(bind)源上的事件。例如,我可能有一个 ListView 收听 CollectionChanged ObservableCollection 上的事件.

如果预期事件源的生命周期超过事件监听器的生命周期,则可能存在内存泄漏,weak event pattern应该使用。

WPF 数据绑定(bind)是否遵循弱事件模式?如果我的 ObservableCollection生命周期比我的ListView 长, 我的 ListView被垃圾收集?

这就是为什么我怀疑 WPF 控件没有实现弱事件模式的原因。如果他们这样做了,我希望这两个 DerivedListView Collected!DerivedTextBlock Collected!输出到控制台。相反,只有 DerivedTextBlock Collected!是。

修复代码中的错误后,将收集两个对象。我不知道该怎么想。

Window1.xaml.cs

using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;

namespace LeakDetector
{
public class DerivedListView : ListView
{
~DerivedListView()
{
Console.WriteLine("DerivedListView Collected!");
}
}

public class DerivedTextBlock : TextBlock
{
~DerivedTextBlock()
{
Console.WriteLine("DerivedTextBlock Collected!");
}
}

public partial class Window1 : Window
{
// The ListView will bind to this collection and listen for its
// events. ObColl will hold a reference to the ListView.
public ObservableCollection<int> ObColl { get; private set; }

public Window1()
{
this.ObColl = new ObservableCollection<int>();
InitializeComponent();

// Trigger an event that DerivedListView should be listening for
this.ObColl.Add(1);

// Get rid of the DerivedListView
this.ParentBorder.Child = new DerivedTextBlock();

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

this.ParentBorder.Child = null;

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

Console.WriteLine("Done");
}
}
}

Window1.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:LeakDetector"
x:Class="LeakDetector.Window1"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Height="300" Width="300"
Title="Leak Detector">
<Border x:Name="ParentBorder">
<local:DerivedListView ItemsSource="{Binding Path=ObColl}" />
</Border>
</Window>

最佳答案

本质上,WPF 控件本身与弱事件没有任何关系。相反,有一些与 WPF 的绑定(bind)引擎相关的类实现了弱事件模式。类(class)PropertyChangedEventManager实现弱事件管理器。如果您使用 Reflector,您会看到几个类在 MS.Internal.Data 命名空间中实现了 IWeakEventListener(特别是一个直接使用 PropertyChangedEventManager 的 MS.Internal.Data.PropertyPathWorker 类)。 WPF 在内部使用这些对象来执行数据绑定(bind)。

ItemsControls 和 CollectionChanged 事件是另一回事,与 Bindings 无关。看,您可以在后面的代码中执行类似“listView.ItemsSource = myObservableCollection”的操作,并且集合更改通知仍然有效。这里根本不涉及绑定(bind)对象。在这里,一组不同的“弱事件相关类”正在发挥作用。 ItemCollectionItemContainerGenerator实现 IWeakEventListener,它们与 CollectionChangedEventManager 一起工作(它实现了 WeakEventManager)。

关于wpf - WPF 控件是否在其绑定(bind)中使用弱事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3712320/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com