首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何调整WPF DataGrid的大小以适应其内容?

如何调整WPF DataGrid的大小以适应其内容?
EN

Stack Overflow用户
提问于 2011-01-02 18:07:20
回答 5查看 83.3K关注 0票数 26

其目的是

我想设置这样的大小为DataGrid (标准,从WPF),以便所有的单元格(文本)将是完全可见的。我有一个带有DockPanel的窗口,里面有DataGrid,所以当我调整窗口大小时,所有嵌套的小部件(DockPanel和DataGrid)都会相应地调整大小。

编辑示例(-1)

假设你有一个100像素宽的窗口,你有一个有一列的DataGrid,它的单元格是“敏捷的棕色狐狸...”(400像素宽)。因此,DataGrid应该调整到400像素(可能更多,因为需要填充),窗口也应该调整到400像素(也应该更多,因为需要填充)。

我没有找到任何标准的方法来做到这一点(AFAIK WPF提供了将内容裁剪到所需宽度的方法,我的问题正好相反),所以我想出了这样一个丑陋的变通办法,效果不是很好。

解决方法

  1. 遍历DataGrid标头(假设它们只是字符串)并计算文本所需的宽度
  2. 遍历每列的DataGrid行(假设它们是TextBlock或TextBox)并计算文本所需的最大宽度--为文本块/文本框添加水平填充,为DataGrid单元格添加水平边距
  3. 求和列的DataGrid ActualWidth与(2)中计算的最大宽度之间的所有差值
  4. 按(3)

中计算的差值增加窗口宽度

问题所在

我做了几次测试,在某些情况下计算的宽度太大(这是一个小问题),而在某些情况下计算的宽度太小。问题从它的核心过程开始--计算TextBox/TextBlock所需的宽度,计算出的宽度总是比它应该的宽度小1个单位(如果我将宽度设置为computed 1,文本中的1个像素总是被裁剪)。

那么,我在这里忽略了哪个因素?,或者更好的-- 是否已经有一些方法可以调整DataGrid的大小以适应其内容?

代码

计算文本所需的宽度(此处为TextBlock):

    public static double TextWidth(this TextBlock widget, string text)
    {
        var formattedText = new FormattedText(text, // can use arbitrary text
                                              System.Globalization.CultureInfo.CurrentCulture,
                                              widget.FlowDirection,
                                              widget.FontFamily.GetTypefaces().FirstOrDefault(),
                                              widget.FontSize, 
                                              widget.Foreground);

        return formattedText.Width+widget.Padding.Left+widget.Padding.Right;
    }

调整窗口大小以适应DataGrid内容(ugly_factor是一个丑陋的变通方法;-)因为我不知道如何正确地修复它,所以我将其设置为1.3,这样我的窗口就“永远”不会太小:

    public static void AdjustWidthToDataGrid(this Window window, DataGrid dataGrid, double ugly_factor)
    {
        var max_widths = dataGrid.Columns.Select(it => window.TextWidth(it.Header as string) 
                                                                        * ugly_factor).ToArray();

        foreach (var row in Enumerable.Range(0, dataGrid.Items.Count))
            foreach (var col in Enumerable.Range(0, dataGrid.Columns.Count))
            {
                var cell = dataGrid.GetCell(row, col);
                double width = 0;
                if (cell.Content is TextBlock)
                    width = (cell.Content as TextBlock).TextWidth();
                else if (cell.Content is TextBox)
                    width = (cell.Content as TextBox).TextWidth();

                if (cell.Content is FrameworkElement)
                {
                    var widget = cell.Content as FrameworkElement;
                    width = width + widget.Margin.Left + widget.Margin.Right;
                }

                max_widths[col] = Math.Max(max_widths[col], 
                                           width*ugly_factor+cell.Padding.Left+cell.Padding.Right);
            }

        double width_diff = 0;

        foreach (var col in Enumerable.Range(0, dataGrid.Columns.Count))
            width_diff += Math.Max(0,max_widths[col] - dataGrid.Columns[col].ActualWidth);

        if (width_diff > 0)
            window.Width = window.ActualWidth+ width_diff;
    }
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4577944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档