Как отсортировать данные в соответствии с цветом фона строки? - PullRequest
0 голосов
/ 10 июня 2019

У меня есть DataGridView в проекте WinForms (c #).Его строки форматируются, если выполняется определенное условие.Вот код:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    foreach (DataGridViewRow Myrow in dataGridView1.Rows)
    {
        string BEFORE_HYPHEN = GetUntilOrEmpty(Convert.ToString(Myrow.Cells[2].Value));
        if (BEFORE_HYPHEN.Length == 2)
        {
        }
        else
        {
            Myrow.DefaultCellStyle.BackColor = Color.Yellow;
            Myrow.DefaultCellStyle.ForeColor = Color.Black;
        }
    }
}

Теперь я хочу, чтобы строки с желтым BackColor отображались первыми (сортировка по цвету фона строки).

Ответы [ 2 ]

3 голосов
/ 10 июня 2019

Проблемы с окраской

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

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

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

Сортировка базы данных DataGridView

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

См. Эти вопросы для идей реализации:

Обновление: поскольку вы привязываете сетку к датируемым данным, мы можем использовать код, опубликованный @ TaW в Настраиваемый порядок сортировки - DataGridView как отправная точка.

Вот упрощенный пример:

//we'll need to process this table
var table = DATASET_DATA.Tables[0];

//First, add a column for BackColor and calculate values
//Here I use a simple column of type Color and default order (alphabetically, by color name)
//If you need a more complicated sorting, consider creating a numeric (BackColorOrder) column instead
table.Columns.Add("BackColor", typeof(Color));
foreach (DataRow row in table.Rows)
{
    string BEFORE_HYPHEN = GetUntilOrEmpty(Convert.ToString(row[2]));
    if (BEFORE_HYPHEN.Length == 2)
    {
        //white, or whatever your default color is
        row["BackColor"] = Color.White;
    }
    else
    {
        row["BackColor"] = Color.Yellow;
    }
}

//Assign a sorted binding source as a datasource
var bs = new BindingSource
{
    DataSource = table,
    Sort = "BackColor ASC"
};
dataGridView1.DataSource = bs;
//Hide backcolor from the grid
//If this column has a meaning in your application (some kind of a status?)
//Consider displaying it, so the user will be able to change sort order
dataGridView1.Columns["BackColor"].Visible = false;

...

/// <summary>
/// We're using DataBindingComplete to calculate color for all rows
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
     //Assign a pre-calculated BackColor for grid rows
     foreach (DataGridViewRow row in dataGridView1.Rows)
     {
          row.DefaultCellStyle.BackColor = (Color)row.Cells["BackColor"].Value;
     }
}

Вот полный, работающий пример . Результат выглядит так:

enter image description here

Сортировка DataGridView без привязки к данным

Если ваше представление данных имеет не привязку к данным, вы сможете отсортировать его, используя Sort(IComparer comparer):

dataGridView1.Sort(new BackColorComparer());

...
/// <summary>
/// Custom comparer will sort rows by backcolor
/// </summary>
private class BackColorComparer : System.Collections.IComparer
{
     public int Compare(object x, object y)
     {
          var row1 = (DataGridViewRow)x;
          var row2 = (DataGridViewRow)y;
          //Sorting by color names, replace with custom logic, if necessary
          return string.Compare(
               row1.DefaultCellStyle.BackColor.ToString(),
               row2.DefaultCellStyle.BackColor.ToString());
     }
}

Обязательно запускайте этот код только после того, как вы закончили вычисление BackColor для всех строк.

1 голос
/ 10 июня 2019

вам нужно изменить свой источник данных вида данных следующим образом:

var sorted = DATASET_DATA.Tables[0].Select().OrderBy(row =>
{
    string BEFORE_HYPHEN = GetUntilOrEmpty(Convert.ToString(row.ItemArray[2]));
    return BEFORE_HYPHEN.Length == 2;
});
dataGridView1.DataSource = sorted.CopyToDataTable(); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...