C# 如何在不删除排序工具的情况下删除datagridview中的排序图示符

C# 如何在不删除排序工具的情况下删除datagridview中的排序图示符,c#,winforms,datagridview,datagridviewcolumn,columnsorting,C#,Winforms,Datagridview,Datagridviewcolumn,Columnsorting,如何从DataGridView的列标题中删除排序标志符号,而不删除其排序功能 我正在使用C#开发windows窗体应用程序,我想从datagridview生成报告,datagridview列宽将在报告列中指定,其中datagridview列包含with of sorting glyph,在我的情况下,这是不必要的空间,我想将其从ColumnHeader中排除。在WinForms中无法执行此操作,除非您编写一个定制的数据网格视图来满足您的需求,否则我认为这对您的需求来说是一种过度的需求 更新 我已

如何从DataGridView的列标题中删除排序标志符号,而不删除其排序功能


我正在使用C#开发windows窗体应用程序,我想从datagridview生成报告,datagridview列宽将在报告列中指定,其中datagridview列包含with of sorting glyph,在我的情况下,这是不必要的空间,我想将其从ColumnHeader中排除。

在WinForms中无法执行此操作,除非您编写一个定制的数据网格视图来满足您的需求,否则我认为这对您的需求来说是一种过度的需求

更新

我已经为按钮、画布控件创建了自定义进度条,但没有创建自定义数据网格视图。也就是说,这是我的想法

实际上,您创建了一个新的
UserControl
,并向其中添加了一个普通的DataGridView,然后删除了标题。现在在DataGridControl上方添加面板,该控件在列标题处“起作用”。您必须处理所有事件,如单击标题进行排序、调整标题大小以调整列大小,以及调用DataGridView上的方法来执行相同的操作

如果您想要在用户向下滚动时隐藏列标题的效果,您还必须手动执行

对不起,我不能给你一个比这更坚实的起点。如果您是创建自定义控件的新手,请尝试创建自定义按钮(EX:左边有一个图像)或进度条,也可以在中间显示进度百分比。你会感觉到你能做什么


如果您使用WPF,我认为这样的事情很容易完成。

使用自定义单元格绘制实际上很容易做到

您只需处理
DataGridView
CellPaint
事件:

dataGridView1.CellPainting += new DataGridViewCellPaintingEventHandler(dataGridView1_CellPainting);
void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    DataGridViewColumn c = dataGridView1.Columns[e.ColumnIndex];

    if (c.AutoSizeMode == DataGridViewAutoSizeColumnMode.None)
    {
        Size s = TextRenderer.MeasureText(dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString(), dataGridView1.Font);
        if (s.Width > c.Width)
        {
            c.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
        }
    }

}
在处理程序中,执行如下操作:

void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.RowIndex == -1)
    {
        e.Paint(e.CellBounds, DataGridViewPaintParts.All &~DataGridViewPaintParts.ContentBackground);

        e.Handled = true;
    }
}
上面的代码非常简单-只需检查当前单元格是否位于标题行(具有-1索引),然后绘制除
ContentBackground
之外的所有内容

我只在我的Windows 7机器上检查了这一点,它看起来很好,似乎内容背景仅用于排序图示符-您需要在目标环境中测试它,以确保不需要再进行任何涉及自定义绘制来保持ContentBackground而不使用图示符


标题单元格的宽度仍将包括图示符的空间。我通常会接受这样的观点,因为更改这一点会变得有点混乱,但是如果您必须使宽度适合文本,那么下面类似的内容将起作用

首先在
DataGridView
DataBindingComplete
事件中设置宽度:

void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{        
    if (dataGridView1.AutoSizeColumnsMode == DataGridViewAutoSizeColumnsMode.AllCells)
    {
        // Loop over all the columns
        foreach (DataGridViewColumn c in dataGridView1.Columns)
        {
            // Work out the size of the header text
            Size s = TextRenderer.MeasureText(c.HeaderText, dataGridView1.Font);

            // Change the autosize mode to allow us to see if the header cell has the 
            // longest text
            c.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
            if (s.Width + 10 > c.Width)
            {
                // If the header cell is longest we set the column width
                c.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
                c.Width = s.Width + 10;
            }
            else
            {
                // If the header cell is not longest, reset the autosize mode
                c.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            }
        }
    }
}
完成此操作后,当单元格文本长于标题时,仍然需要允许列自动调整大小

为此,我使用了
CellValueChanged
事件:

dataGridView1.CellPainting += new DataGridViewCellPaintingEventHandler(dataGridView1_CellPainting);
void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    DataGridViewColumn c = dataGridView1.Columns[e.ColumnIndex];

    if (c.AutoSizeMode == DataGridViewAutoSizeColumnMode.None)
    {
        Size s = TextRenderer.MeasureText(dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString(), dataGridView1.Font);
        if (s.Width > c.Width)
        {
            c.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
        }
    }

}

我在尝试使右对齐的标题文本与单元格内容对齐时遇到了相同的问题(标题文本没有完全右对齐,这在一行数字中看起来很傻。)我在其他dgv中注意到有可能挤出字形

不管怎样,使用真正简单的解决方案,用前导空格填写标题文本,并将标题单元格换行模式设置为false。例如:

    dgv.Columns["Width"].HeaderText = "        Width";
    dgv["Width"].HeaderCell.Style.WrapMode = DataGridViewTriState.False;

可能需要花点时间才能获得正确的前导空格数,但结果令人满意。(不知道它是否适用于尾随空格,太晚了,无法尝试。)

如果我制作自定义datagridview,那么我该怎么做?thnx用于回复,但这可能是一项巨大的工作,我正在开发一个应用程序,我无法尝试这种类型的所有就绪运行模块的实现。thnx用于回复是的,在WinForms中创建自定义控件是一项艰巨的任务,需要大量测试。在这种情况下,您可能必须对当前结果“确定”。我想删除图示符大小。其中包括wgeb AutoSizeColumn calclulates在启用模式时列的大小AllCells@HaiderAliWajihi这变得相当棘手——我会再考虑一下,但想不出一个好办法。宽度要么是标题单元格,要么足够长以容纳单元格中最长的内容,这意味着仅基于标题文本设置宽度是行不通的。@HaiderAliWajihi我找到了一种方法。也许有更干净的方法,但我想不出。如果是我,我只会使用自定义绘画,并接受字形的宽度包括在内。但您可能会发现此代码对您有用。非常感谢,我认为这可能有效,我将尝试此代码。然而,通过此解决方案,问题可以消除,但这不是一个好办法。我有一个客户datagridview,它可以以任何方式使用,我们不能设置WrapMode=false。