You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 10:20:03