我发表了很多关于数据网格泄漏的文章,并且找不到正确的方法。 这是一些重现的代码。它有datagrid和buttoon,每次按下按钮时,它会用随机数填充表,并占用10mb的内存,而不释放它。 绑定到TextBlock不会导致内存泄漏,但我需要文本框双向绑定。
<Window x:Class="test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<DataGrid Name="dg" Grid.Row="0" AutoGenerateColumns="False" ItemsSource="{Binding}">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Text0}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Text1}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Text2}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Text3}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Text4}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Text5}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Text6}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Text7}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Text8}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Text9}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Button Content="update" Grid.Row="1" Width="Auto" Height="Auto" Click="Button_Click"></Button>
</Grid>
namespace test
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public ObservableCollection<obj> res;
private void Button_Click(object sender, RoutedEventArgs e)
{
res = new ObservableCollection<obj>();
for (var i = 0; i < 20; i++)
{
res.Add(new obj
{
Text0 = ((new Random()).NextDouble() * 100).ToString(),
Text1 = ((new Random()).NextDouble() * 100).ToString(),
Text2 = ((new Random()).NextDouble() * 100).ToString(),
Text3 = ((new Random()).NextDouble() * 100).ToString(),
Text4 = ((new Random()).NextDouble() * 100).ToString(),
Text5 = ((new Random()).NextDouble() * 100).ToString(),
Text6 = ((new Random()).NextDouble() * 100).ToString(),
Text7 = ((new Random()).NextDouble() * 100).ToString(),
Text8 = ((new Random()).NextDouble() * 100).ToString(),
Text9 = ((new Random()).NextDouble() * 100).ToString(),
});
}
dg.DataContext = res;
}
}
public class obj : INotifyPropertyChanged
{
private string text0;
public string Text0
{
get
{
return text0;
}
set
{
text0 = value;
NotifyPropertyChanged("Text0");
}
}
private string text1;
public string Text1
{
get
{
return text1;
}
set
{
text1 = value;
NotifyPropertyChanged("Text1");
}
}
private string text2;
public string Text2
{
get
{
return text2;
}
set
{
text2 = value;
NotifyPropertyChanged("Text2");
}
}
private string text3;
public string Text3
{
get
{
return text3;
}
set
{
text3 = value;
NotifyPropertyChanged("Text3");
}
}
private string text4;
public string Text4
{
get
{
return text4;
}
set
{
text4 = value;
NotifyPropertyChanged("Text4");
}
}
private string text5;
public string Text5
{
get
{
return text5;
}
set
{
text5 = value;
NotifyPropertyChanged("Text5");
}
}
private string text6;
public string Text6
{
get
{
return text6;
}
set
{
text6 = value;
NotifyPropertyChanged("Text6");
}
}
private string text7;
public string Text7
{
get
{
return text7;
}
set
{
text7 = value;
NotifyPropertyChanged("Text7");
}
}
private string text8;
public string Text8
{
get
{
return text8;
}
set
{
text8 = value;
NotifyPropertyChanged("Text8");
}
}
private string text9;
public string Text9
{
get
{
return text9;
}
set
{
text9 = value;
NotifyPropertyChanged("Text9");
}
}
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
答案 0 :(得分:1)
TextBox
具有与之关联的Undo
\ Redo
堆栈,并且当它们更改为新值时,它会存储可重新/可撤消的值。因此可能会解释TextBox的未发布的内存。
现在您可能会问,您每次都要设置ItemsSource
新鲜。不应该重新生成新TextBoxes
(以便新生成的TextBox
没有机会持有任何旧 Undo
堆栈。我想Datagrid
会回收ItemsContainer
并重新使用生成的TextBoxes
。
但那只是我的推测!!!
您可以尝试限制Undo
堆栈&amp;重新检查它是否适合你...
http://social.msdn.microsoft.com/Forums/en/wpf/thread/376f7765-1c70-4289-a59b-e27c168a0fa2
答案 1 :(得分:1)
如果您可以使用DataGridTextColumn而不是DataGridTemplateColumn,那么您的内存不会泄漏。
dunno为什么DataGridTemplateColumn有一个memoryleak
编辑:
我也会初始化一次OberservableColletion,只需设置一次datacontext并在button_click中使用clear。
编辑:DataGridTemplateColumn的内存泄漏问题似乎已经消失了.NET4.5