ItemsControl中使用TextBox引发内存泄漏问题求助
WPF TextBox内存泄漏排查(.NET Framework 4.7.2)
问题背景
经dotMemory分析确认,移除ItemsControl的DataTemplate中的TextBox后内存泄漏现象消失,因此锁定问题根源在TextBox组件。已尝试通过样式禁用Undo功能(设置IsUndoEnabled="False"),但泄漏问题仍未解决。
相关代码
简化后的ItemsControl XAML
<ItemsControl Grid.Row="0" Grid.Column="1" x:Name="FieldsView" Background="Transparent"> <ItemsControl.ItemTemplate> <DataTemplate> <Grid Margin="0 5"> <Grid.ColumnDefinitions> <ColumnDefinition MaxWidth="300" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <StackPanel Grid.Column="1"> <Grid> <TextBox Tag="firstname" Text="" /> </Grid> </StackPanel> </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
已禁用Undo的TextBox样式
<Style TargetType="{x:Type TextBox}"> <Setter Property="IsUndoEnabled" Value="False"/> <Setter Property="Background" Value="{StaticResource TextBox.Background}" /> <Setter Property="Opacity" Value="60" /> <Setter Property="BorderThickness" Value="0" /> <Setter Property="FontSize" Value="22pt"/> <Setter Property="FontFamily" Value="Segoe UI Light" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TextBoxBase}"> <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> <ScrollViewer x:Name="PART_ContentHost" Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" /> </Border> <ControlTemplate.Triggers> <Trigger Property="IsFocused" Value="True"> <Setter Property="BorderBrush" Value="#FF7EB4EA" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
数据源绑定代码
private ObservableCollection<RegistrationFieldViewModel> _model; _model = new ObservableCollection<RegistrationFieldViewModel>(visitorTypeSettingInfo.Fields.Select(a => new RegistrationFieldViewModel { Key = a.Key, Mandatory = a.Mandatory, UseAsLookup = a.UseAsLookup, Type = a.Type }).ToList()); FieldsView.ItemsSource = _model;
RegistrationFieldViewModel实现了INotifyPropertyChanged接口
排查方向建议
- 自定义模板验证:替换为TextBox默认模板测试是否仍存在泄漏,排除自定义模板中
PART_ContentHost或其他元素的潜在引用问题。 - 静态资源检查:确认样式中
{StaticResource TextBox.Background}对应的资源对象是否为长期存活实例,是否间接导致TextBox被强引用无法回收。 - 焦点引用清理:TextBox获得焦点后,WPF焦点管理器可能持有强引用,可尝试在容器卸载时手动清除所有TextBox的焦点,排查是否存在焦点相关泄漏。
- 版本BUG与升级:查阅.NET Framework 4.7.2官方BUG列表,确认是否存在TextBox相关泄漏补丁;若允许,升级至.NET Framework 4.8(该版本修复了大量WPF内存泄漏问题)。
- 事件订阅排查:检查是否存在针对TextBox的全局事件(如
TextChanged、PreviewKeyDown)订阅未使用弱引用,导致TextBox被事件发布者持有引用。 - 数据源生命周期管理:确认容器(窗口/用户控件)销毁时,是否清空
ItemsControl.ItemsSource并将_model置为null,避免ViewModel间接持有TextBox引用。
内容的提问来源于stack exchange,提问作者rukiman
相关产品推荐
相关产品推荐

