[英]clearing child controls from wrappanel does not clear memory and references
我有一個包裝面板,用於將標簽應用於圖像。 可以添加和刪除標簽:
問題如下:刪除元素后,memory 不會被釋放,也不會被垃圾回收。
這就是我添加控件的方式:
foreach (MetadataAttribute attribute in metadata.attributes)
{
this.Attributes_StackPanel.Children.Add(new Attribute(attribute));
}
這就是我最初刪除元素的方式:
this.Attributes_StackPanel.Children.Clear();
我找到了有關該主題的多個資源和問題,但似乎沒有一個對我有用:
我在帖子中徘徊,直到我以這樣的令人厭惡的方式結束:
父母:
/// <summary>
/// clears the attribute panel to prepare for new metadata to be loaded
/// </summary>
private void ClearAttributesPanel()
{
for(int i = this.Attributes_StackPanel.Children.Count-1; i > 0; i--)
{
Attribute attr = (Attribute)this.Attributes_StackPanel.Children[i];
attr.Delete();
attr = null;
}
}
xaml:
<UserControl x:Class="Minter_UI.Attribute"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Minter_UI"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" Padding="0.1cm, 0.1cm, 0, 0">
<Grid x:Name="Main_Grid">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="1cm"></ColumnDefinition>
<ColumnDefinition Width="0.5cm"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel x:Name="Stack_Panel" Orientation="Vertical" Grid.Row="0">
<ComboBox x:Name="TraitType_ComboBox" IsEditable="True" Text="TraitType" SelectionChanged="TraitType_ComboBox_SelectionChanged"></ComboBox>
<ComboBox x:Name="Value_ComboBox" IsEditable="True" Text="Value"></ComboBox>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Label Content="MinValue" Grid.Column="0"></Label>
<Label Content="MaxValue" Grid.Column="1"></Label>
<TextBox x:Name="MinValue_TextBox" Grid.Row="1" Grid.Column="0"></TextBox>
<TextBox x:Name="MaxValue_TextBox" Grid.Row="1" Grid.Column="1"></TextBox>
</Grid>
</StackPanel>
<Button x:Name="Delete_Button" Content="X" Background="LightCoral" Grid.Column="1" Click="Delete_Button_Click"></Button>
</Grid>
</UserControl>
屬性刪除:
public void Delete()
{
// unregister events
this.TraitType_ComboBox.SelectionChanged -= this.TraitType_ComboBox_SelectionChanged;
this.Delete_Button.Click -= this.Delete_Button_Click;
// main grid
this.Main_Grid.Children.Clear();
this.Main_Grid = null;
// stack panel
this.Stack_Panel.Children.Clear();
this.Stack_Panel = null;
// textboxes
this.MinValue_TextBox.Text = null;
this.MinValue_TextBox = null;
this.MaxValue_TextBox.Text= null;
this.MaxValue_TextBox = null;
//comboboxes
this.TraitType_ComboBox.ItemsSource= null;
this.TraitType_ComboBox.SelectedItem= null;
this.TraitType_ComboBox.Text= null;
this.TraitType_ComboBox = null;
this.Value_ComboBox.ItemsSource = null;
this.Value_ComboBox.SelectedItem = null;
this.Value_ComboBox.Text = null;
this.Value_ComboBox = null;
// delete button
this.Delete_Button.Content = null;
this.Delete_Button = null;
// clear all x:name properties
this.UnregisterName("Stack_Panel");
this.UnregisterName("MinValue_TextBox");
this.UnregisterName("MaxValue_TextBox");
this.UnregisterName("TraitType_ComboBox");
this.UnregisterName("Value_ComboBox");
this.UnregisterName("Main_Grid");
this.UnregisterName("Delete_Button");
// remove self from parent
((Panel)this.Parent).Children.Remove(this);
}
不過,這不起作用。 在足夠的重新加載之后,我可以在堆中找到數千個對組合框和文本面板以及哈希表的引用。 一段時間后,垃圾收集器變得瘋狂但從未真正清除任何元素。
我不知道這是不是這樣做的方法,但它有效:
public void SetAttribute(MetadataAttribute attribute)
{
// you need to extend the function, its just an example
this.TraitType_ComboBox.Text = attribute.trait_type.ToString();
this.Value_ComboBox.Text = attribute.@value.ToString();
this.MinValue_TextBox.Text = attribute.min_value.ToString();
this.MaxValue_TextBox.Text = attribute.max_value.ToString();
}
Queue<Attribute> AttributeReuseElements = new Queue<Attribute>();
private void ClearAttributesPanel()
{
for(int i = this.Attributes_StackPanel.Children.Count-1; i > 0; i--)
{
AttributeReuseElements.Enqueue((Attribute)this.Attributes_StackPanel.Children[i]);
this.Attributes_StackPanel.Children.RemoveAt(i);
}
}
foreach (MetadataAttribute attribute in CollectionInformation.Information.LikelyAttributes)
{
if (AttributeReuseElements.Count > 0)
{
Attribute attr = AttributeReuseElements.Dequeue();
attr.SetAttribute(attribute);
this.Attributes_StackPanel.Children.Add(attr);
}
else
{
this.Attributes_StackPanel.Children.Add(new Attribute(attribute));
}
}
這不會忽略手動按下控件的刪除按鈕導致的 memory 泄漏,但這可能可以忽略不計。 但是,無論何時重新加載信息,元素都會被回收而不是被銷毀並重新創建。
如果您不確保正確清除所有字段和值,這可能會產生一些影響。 例如,您可能會從 previus 屬性中找到值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.