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

自定义DataGrid行标题嵌入TextBox后,行标题无法随内容自适应调整大小

解决WPF DataGrid行标题随TextBox内容自适应收缩的问题

我太懂这种自定义DataGrid细节踩坑的感觉了——明明TextBox内容已经变短,行标题却死抱着之前的宽度不放,看起来特别别扭。咱们一步步来解决这个问题:

核心原因

WPF布局系统默认有点“懒”,元素一旦撑开后,不会自动主动收缩尺寸,除非你明确告诉它重新计算。加上DataGridRowHeader默认的模板可能没有设置成完全跟随内容尺寸,就导致了这个问题。

具体解决方案

1. 先给DataGrid设置自动行标题宽度

首先确保你的DataGrid没有固定行标题宽度,让它能跟着内容走:

<DataGrid x:Name="YourDataGrid"
          RowHeaderWidth="Auto"  <!-- 关键:不要设固定值 -->
          ...>
    <!-- 你的列定义和内容 -->
</DataGrid>

2. 自定义DataGridRowHeader的模板

接下来要修改行标题的模板,让里面的TextBox能正确影响容器尺寸,并且允许收缩:

<Window.Resources>
    <Style TargetType="{x:Type DataGridRowHeader}">
        <Setter Property="Width" Value="Auto"/>
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridRowHeader}">
                    <Border x:Name="RowHeaderBorder"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <!-- TextBox设置为宽度自适应内容,不要撑满容器 -->
                        <TextBox x:Name="RowHeaderInput"
                                 Text="{Binding RowHeaderText, Mode=TwoWay}"  <!-- 替换成你的绑定属性 -->
                                 TextChanged="RowHeaderInput_TextChanged"
                                 HorizontalAlignment="Left"
                                 Width="Auto"
                                 Margin="4"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

3. 在TextBox文本变化时强制触发布局更新

最后,在后台代码里处理TextChanged事件,手动让行标题重新计算尺寸——这是解决“不收缩”问题的关键:

private void RowHeaderInput_TextChanged(object sender, TextChangedEventArgs e)
{
    var textBox = sender as TextBox;
    var rowHeader = textBox?.TemplatedParent as DataGridRowHeader;
    if (rowHeader == null) return;

    // 先让TextBox重新计算自身尺寸
    textBox.InvalidateMeasure();
    // 再强制行标题重新测量和排列
    rowHeader.InvalidateMeasure();
    rowHeader.InvalidateArrange();
    // 最后触发DataGrid整体更新,确保行标题列宽度同步
    YourDataGrid.UpdateLayout();
}

// 要是需要找DataGrid的父元素(如果模板里拿不到直接引用的话),可以加这个辅助方法
private T FindVisualParent<T>(DependencyObject child) where T : DependencyObject
{
    var parent = VisualTreeHelper.GetParent(child);
    if (parent == null) return null;
    return parent is T target ? target : FindVisualParent<T>(parent);
}

额外注意点

  • 不要给TextBox设置固定宽度,一定要让它的Width为Auto,HorizontalAlignment设为Left(或者Center,但Left更符合输入习惯)
  • 如果你的行标题有其他装饰元素(比如图标),要确保它们的尺寸也不会固定,避免限制行标题的收缩
  • 测试时多输入几次长短不同的文本,确认收缩和撑开都能正常工作

内容的提问来源于stack exchange,提问作者Will

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:39:40