想象一下 aUserControl在 aListBox中有CheckBoxa DataTemplate。在ItemsSource對ListBox一些全域串列。在CheckBox具有Checked/Unchecked連接到它的活動。
<ListBox ItemsSource="{Binding Source={x:Static a:MainWindow.Source}}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type a:Data}">
<CheckBox Content="{Binding Path=Name}"
Checked="ToggleButton_OnChecked"
Unchecked="ToggleButton_OnUnchecked"
IsChecked="{Binding Path=IsEnabled}"
Padding="10"
VerticalContentAlignment="Center"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
我正在主視窗的日志中記錄加載/卸載/檢查/未檢查事件。
private void ToggleButton_OnChecked(object sender, RoutedEventArgs e)
{
Log("Checked");
}
private void ToggleButton_OnUnchecked(object sender, RoutedEventArgs e)
{
Log("Unchecked");
}
private void UserControl1_OnLoaded(object sender, RoutedEventArgs e)
{
Log("Loaded");
}
private void UserControl1_OnUnloaded(object sender, RoutedEventArgs e)
{
Log("Unloaded");
}
主視窗具有UserControl1實體的動態串列(僅從一個開始)。有添加/洗掉按鈕允許我添加更多實體。
<UniformGrid Rows="2">
<DockPanel>
<Button DockPanel.Dock="Top" Click="Add">Add</Button>
<Button DockPanel.Dock="Top" Click="Remove">Remove</Button>
<ListBox x:Name="ListBox">
<local:UserControl1 />
</ListBox>
</DockPanel>
<ListBox ItemsSource="{Binding ElementName=This,Path=Log}" FontFamily="Courier New"/>
</UniformGrid>
視窗的代碼隱藏:
private void Add(object sender, RoutedEventArgs e)
{
ListBox.Items.Add(new UserControl1());
}
private void Remove(object sender, RoutedEventArgs e)
{
if (ListBox.Items.Count == 0) return;
ListBox.Items.RemoveAt(0);
}
When I run the app there is just one UserControl1 instance. If I add one more and then immediately remove one of them, then click the one and only checkbox on the screen, I see two "Checked" events logged. If I now uncheck it, there are two "Unchecked" events (even though "Unloaded" event was previously clearly logged. The hex numbers on the left show the output of a GetHashCode() which clearly shows the events were handled by distinct UserControl1 instances.

So even though one of UserControl1 gets unloaded, the events don't seem to get unsubscribed automatically. I have tried upgrading to NET Framework 4.8 to no avail. I see the same behavior. If I add 10 new controls and remove them immediately, I will observe 10 "Checked" or "Unchecked" events.
我曾嘗試搜索類似的問題,但找不到。是我遺漏了什么還是我剛剛遇到了一個錯誤?尋找解決方法。
GitHub 上提供了完整的源代碼。https://github.com/wpfwannabe/datacontext-event-leak
uj5u.com熱心網友回復:
在MVVM模式中,視圖被系結到視圖模型并且在垃圾收集完成它的作業時不會存活。
在您提供的示例中,視圖模型是一個靜態物件,根據定義不能被垃圾收集,因此視圖也不能被垃圾收集。
沒有自動解除系結,因為你可以重復使用的用戶控制元件的實體(也可以是Loaded和UnLoaded多次)。
修復此記憶體泄漏的最簡單1方法是在unload上進行解除系結:
濕巾
// First give the ListBox a name
<ListBox x:Name="ListBox" ItemsSource="{Binding Source={x:Static a:MainWindow.Source}}">
背后的代碼
private void UserControl1_OnUnloaded(object sender, RoutedEventArgs e)
{
Log("Unloaded");
ListBox.ItemsSource = null;
}
1:正確的方法是將靜態串列包裝在專用的串列視圖模型中,使視圖模型可丟棄(在處置時從靜態串列中解除包裝器的系結),在移除時處置視圖模型。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/349413.html
