Как удалить глиф сортировки в datagridview, не удаляя средство сортировки

Как удалить глиф сортировки из заголовков столбцов в DataGridView, не удаляя его функции сортировки.

Я работаю над приложением формы Windows на С#, я хочу создать отчет из представления данных, где ширина столбца представления данных будет назначаться в столбце отчета, где, поскольку столбец DataGridView включает глиф сортировки, в моем случае это ненужное пространство, я хотите исключить его из ColumnHeader.


person Haider Ali Wajihi    schedule 11.08.2012    source источник


Ответы (3)


На самом деле это довольно легко сделать, используя пользовательскую раскраску ячеек.

Все, что вам нужно сделать, это обработать событие DataGridView CellPainting:

dataGridView1.CellPainting += new DataGridViewCellPaintingEventHandler(dataGridView1_CellPainting);

И в обработчике сделать что-то вроде этого:

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 без глифа.


Ширина ячейки заголовка по-прежнему будет включать пространство для глифа. В целом я бы согласился с тем, что, поскольку изменение этого становится немного беспорядочным, но если вам нужно, чтобы ширина соответствовала тексту, тогда будет работать что-то вроде следующего.

Сначала установите ширину в событии DataBindingComplete элемента DataGridView:

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:

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;
        }
    }

}
person David Hall    schedule 11.08.2012
comment
я хочу удалить размер глифа. который включен wgeb AutoSizeColumn вычисляет размер столбца, когда режим AllCells - person Haider Ali Wajihi; 12.08.2012
comment
@HaiderAliWajihi, это становится довольно сложно - я еще подумаю об этом, но не могу придумать хорошего способа. Ширина должна быть либо ячейкой заголовка, либо быть достаточно длинной для самого длинного содержимого из ячейки, что означает, что установка ширины только на основе текста заголовка не будет работать. - person David Hall; 12.08.2012
comment
@HaiderAliWajihi Я нашел способ сделать это. Может быть, есть более чистый метод, но я не могу придумать его. Если бы это был я, я бы просто использовал пользовательскую раскраску и согласился с включенной шириной глифа. Но вы можете обнаружить, что этот код работает для вас. - person David Hall; 12.08.2012
comment
Большое спасибо, я думаю, это может сработать, я попробую этот код. - person Haider Ali Wajihi; 13.08.2012

Вы не можете сделать это в WinForms, если только вы не напишете собственное представление сетки данных, чтобы удовлетворить ваши потребности, что, я бы сказал, излишне для вашего требования.

ОБНОВЛЕНИЕ

Я создал настраиваемые индикаторы выполнения для кнопок и элементов управления холстом, но не создавал пользовательское представление сетки данных. Тем не менее, вот моя идея сделать это...

По сути, вы создаете новый UserControl, добавляете к нему обычный DataGridView и удаляете заголовки. Теперь добавьте панель над DataGridControl, которая «воздействует» на заголовки столбцов. Вам придется обрабатывать все события, например щелкать заголовки для сортировки, изменять их размер для изменения размера столбцов и вызывать методы в DataGridView, чтобы сделать то же самое.

Если вам нужен эффект сокрытия заголовков столбцов при прокрутке пользователем вниз, вам также придется сделать это вручную.

Извините, я не могу дать вам надежную отправную точку, кроме этой. Если вы новичок в создании настраиваемых элементов управления, попробуйте создать пользовательскую кнопку (например, с изображением слева) или индикатор выполнения, который также отображает процент выполнения в середине. Вы почувствуете, на что вы способны.

Если вы используете WPF, я думаю, что такие вещи можно легко выполнить.

person Madushan    schedule 11.08.2012
comment
если я создам собственный datagridview, то как я могу это сделать? - person Haider Ali Wajihi; 11.08.2012
comment
спасибо за ответ, но это может быть огромная работа, я работаю над приложением, которое находится в середине своей разработки, и я не могу попробовать этот тип реализации уже запущенных модулей. thnx для ответа еще раз - person Haider Ali Wajihi; 11.08.2012
comment
Да, создание пользовательского элемента управления в WinForms — это огромная задача, требующая МНОГО тестирования. В этом случае вам, возможно, придется согласиться с текущим результатом. - person Madushan; 11.08.2012

Я столкнулся с той же проблемой, когда пытался выровнять текст заголовка по правому краю, чтобы он соответствовал содержимому ячейки (выглядит глупо в ряду чисел, поскольку текст заголовка также не полностью выровнен по правому краю). Я заметил, что в других dgv можно было выдавить глиф.

Во всяком случае, очень простое решение, заполните текст заголовка начальными пробелами и установите для режима переноса ячейки заголовка значение false. пример:

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

может потребоваться немного поэкспериментировать, чтобы получить правильное количество начальных пробелов, но результат приятен. (Не знаю, работает ли это с конечными пробелами, слишком поздно, чтобы пытаться.)

person Rob    schedule 04.02.2013
comment
однако из этого решения проблема может быть устранена, но это не очень хороший трюк. У меня есть представление данных клиента, которое можно использовать любым способом, и мы не можем установить WrapMode = false. - person Haider Ali Wajihi; 07.02.2013