[英]Disposing a UserControl loaded via ContentPresenter
我的mainView(窗口)上有以下代碼
<StackPanel>
<Button Click="OnLoadChildView">Load</Button>
<Button Click="OnUnloadChildView">UnLoad</Button>
<ContentPresenter Content="{Binding ChildViewModel}"/>
</StackPanel>
和這段代碼在我的ChildView(UserControl)上
<StackPanel>
<local:MyListBox ItemsSource="{Binding Items}">
</local:MyListBox>
</StackPanel>
這是MainView的代碼
public MainView()
{
InitializeComponent();
MainViewModel vm = new MainViewModel();
this.DataContext = vm;
}
public MainViewModel Model { get { return this.DataContext as MainViewModel; } }
private void OnLoadChildView(object sender, System.Windows.RoutedEventArgs e)
{
this.Model.ChildViewModel = new ChildViewModel();
}
private void OnUnloadChildView(object sender, System.Windows.RoutedEventArgs e)
{
this.Model.ChildViewModel = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
這是我的其他代碼:
public class MyListBox : ListBox
{
public MyListBox() { Debug.WriteLine("Created instance of MyListBox:" + this.GetHashCode()); }
~MyListBox() { Debug.WriteLine("destroyed instance of MyListBox:" + this.GetHashCode()); }
}
public class ViewModelBase : INotifyPropertyChanged
{
private PropertyChangedEventHandler _propertyChanged;
public event PropertyChangedEventHandler PropertyChanged
{
add
{
_propertyChanged += value;
}
remove
{
_propertyChanged -= value;
}
}
protected virtual void OnPropertyChanged(string property)
{
if (_propertyChanged != null)
{
_propertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
public class MainViewModel : ViewModelBase
{
private ChildViewModel _ChildViewModel;
public ChildViewModel ChildViewModel
{
get { return _ChildViewModel; }
set
{
if (_ChildViewModel != value)
{
_ChildViewModel = value;
OnPropertyChanged(nameof(ChildViewModel));
}
}
}
}
public class ChildViewModel : ViewModelBase
{
public ChildViewModel()
{
Debug.WriteLine("Created instance of ChildViewModel:" + this.GetHashCode());
this.Items = new List<string>(new string[] { "ABC", "DEF" });
}
~ChildViewModel()
{
this.Items = null;
Debug.WriteLine("destroyed instance of ChildViewModel:" + this.GetHashCode());
}
private IEnumerable<string> _Items;
public IEnumerable<string> Items
{
get { return _Items; }
set
{
if (_Items != value)
{
_Items = value;
OnPropertyChanged(nameof(Items));
}
}
}
}
我使用應用程序資源處理視圖:
<Application.Resources>
<DataTemplate DataType="{x:Type vm:ChildViewModel}">
<vw:ChildView/>
</DataTemplate>
</Application.Resources>
當我啟動應用程序並單擊加載按鈕,然后單擊卸載按鈕兩次時,得到以下輸出:
Created instance of ChildViewModel:2670961
Created instance of ChildView:2080614
Created instance of MyListBox:33397791
destroyed instance of ChildViewModel:2670961
當我將ChildView的XAML更改為:
<StackPanel>
<local:MyListBox>
</local:MyListBox>
</StackPanel>
因此刪除綁定,再次啟動我的啟動應用程序,單擊加載按鈕,然后單擊卸載按鈕兩次,我得到了以下信息:
Created instance of ChildViewModel:30767036
Created instance of ChildView:50297887
Created instance of MyListBox:5453341
destroyed instance of MyListBox:5453341
destroyed instance of ChildViewModel:30767036
Destroyed instance of ChildView:50297887
因此,看來我真的無法擺脫WPF的NotifyPropertyChangedEventHandler,因此我的列表框和視圖不會被處理掉。 我該如何實現? 因為我認為這很清楚,所以刪除Binding並不是一種選擇。
好的,我要結束這件事,因為實際上清理是按照正確的方式進行的,但是似乎GarbageCollector確實花了一些時間來考慮在win8.1機器上進行清理。 在“卸載”按鈕上單擊約10-15次后,將進行清理。 在win7機器上,清除總是在第二次單擊時進行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.