Progressbar для загрузки данных в DataGridView с использованием DataTable

У меня есть DataGridView, в котором я загружаю данные из базы данных SQL-сервера. Когда я загружаю данные, это занимает довольно много времени.

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

Я не хочу, чтобы кто-нибудь сделал для меня полностью рабочий код. Я просто хотел бы знать, как это можно сделать.

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

DTGdataTable = new DataTable();
SqlDataAdapter SDA = new SqlDataAdapter
SDA.Fill(DTGdataTable);
dataGridView1.DataSource = DTGdataTable ;

Спасибо всем за ваше время.

Ответ 1

Если проблема в том, что для получения данных из базы данных требуется много времени, у меня есть возможное решение для вас:

    private void buttonLoad_Click(object sender, EventArgs e)
    {
        progressBar.Visible = true;
        progressBar.Style = ProgressBarStyle.Marquee;
        System.Threading.Thread thread = 
          new System.Threading.Thread(new System.Threading.ThreadStart(loadTable));
        thread.Start();
    }

    private void loadTable()
    {
        // Load your Table...
        DataTable table = new DataTable();
        SqlDataAdapter SDA = new SqlDataAdapter();
        SDA.Fill(table);
        setDataSource(table);
    }

    internal delegate void SetDataSourceDelegate(DataTable table);
    private void setDataSource(DataTable table)
    {
        // Invoke method if required:
        if (this.InvokeRequired)
        {
            this.Invoke(new SetDataSourceDelegate(setDataSource), table);
        }
        else
        {
            dataGridView.DataSource = table;
            progressBar.Visible = false;
        }
    }

Поместите метод, загружающий данные в другой поток, и установите источник данных, когда он будет завершен. Требуется вызов. Если вы хотите показывать процентные значения в панели прогресса, не используйте стиль "Marquee" и добавьте еще одну функцию и делегат, которую вы можете вызвать для установки значения индикатора выполнения.

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

Надеюсь, это поможет.

Ответ 2

Попробуйте это... Это должен быть самый быстрый маршрут...

1) Add a button control.
2) Add a datagridview control.
3) Add a single column into the datagridview control.
4) Add a progressbar control.
5) Leave them all with default names.

В событии button1_Click добавьте этот фрагмент кода...

int maxnumber = 1000;
progressBar1.Value = 0;
progressBar1.Maximum = maxnumber;
for (int x = 0; x <= maxnumber - 1; x++)
{
    Application.DoEvents();
    dataGridView1.Rows.Add(new string[] {Convert.ToString(x)});
    progressBar1.Value += 1;
    label1.Text = progressBar1.Value.ToString();
}

Что это. Редактируйте в соответствии с вашими потребностями. Это не полный точный код, который вам нужен, но он должен вас начать. Я взял на себя смелость объявить maxnumber, чтобы удерживать предел прогресса. В вашем случае это должен быть счетчик строк вашей базы данных, и он вычитается на 1, поскольку индекс всегда начинается с нуля:)

Приведенный выше метод является однопоточным, что означает, что вы все еще не можете выполнять многозадачность, пока ваш цикл еще не выполнен. В некоторых случаях, в зависимости от алгоритма кода, использование однопоточного метода может быть быстрее, чем для маршрута многопоточности. Во всяком случае, второй метод будет использовать фонового работника. Это чаще всего предпочитают люди, так как пользователь все еще может делать что-то во время загрузки списка. Вид вроде инсталляторов, где вы можете отменить установку, даже если она находится в середине чего-то. На веб-сайте ниже вы должны начать. Код находится в VB.NET, но его можно легко преобразовать в С#:)

http://social.msdn.microsoft.com/Forums/vstudio/en-US/efd7510c-43ed-47c4-86a3-1fa350eb0d30/fill-datagridview-using-backgroundworker-progressbar?forum=vbgeneral

Ответ 3

Проблема заключается в том, что все данные загружаются вместе и возвращаются из базы данных. Вам нужно получить ход загрузки данных. Это можно сделать из базы данных.

  • Получить счетчик строк данных из базы данных. (Этот запрос вернет один номер, поэтому он будет быстрее).

  • Получить данные по частям (стратегия разделения и завоевания), вы можете использовать запросы базы данных OFFSET и FETCH. (Это возвращаемая часть данных для каждого вызова) OFFSET и FETCH доступны в другой базе данных. В MSSQL он был представлен в версии 2012.

Когда мы получаем данные по частям с сервера, мы можем рассчитать прогресс.

Ответ 4

В вашем коде эта строка занимает большую часть времени обработки:

SDA.Fill(DTGdataTable);

Поэтому я думаю, что самое главное - следить за ходом выполнения, пока это выполняется. Для этого вам сначала нужно знать, сколько строк вы ожидаете. SQLDataAdapter не может предоставить эту информацию, поэтому сначала вам нужно запустить дополнительный запрос COUNT (*), чтобы получить этот номер. Затем вы можете использовать это как Максимум на своем ProgressBar.

Мой фактический код загрузки основан на решении Майкла Хофмайера, но вместо использования режима ProgressBar в режиме Marquee я бы подавал ему реальные данные о ходе работы с помощью Timer Control. Итак, в вашей форме вы добавляете элемент управления Timer (с именем progressTimer в моем примере), установите его интервал до 100 мс и Enabled равным false. Затем код будет выглядеть следующим образом:

private DataTable table = null;

private void buttonLoad_Click(object sender, EventArgs e)
{
    // TODO: Select the row count here and assign it to progressBar.Maximum

    progressBar.Visible = true;             
    System.Threading.Thread thread = 
      new System.Threading.Thread(new System.Threading.ThreadStart(loadTable));
    thread.Start();
    progressTimer.Enabled = true;
}

private void loadTable()
{
    // Load your Table...
    this.table = new DataTable();
    SqlDataAdapter SDA = new SqlDataAdapter();
    SDA.Fill(table);
    setDataSource(table);
}

internal delegate void SetDataSourceDelegate(DataTable table);
private void setDataSource(DataTable table)
{
    // Invoke method if required:
    if (this.InvokeRequired)
    {
        this.Invoke(new SetDataSourceDelegate(setDataSource), table);
    }
    else
    {
        progressTimer.Enabled = false;
        dataGridView.DataSource = table;
        progressBar.Visible = false;
    }
}

private void progressTimer_Tick(object sender, EventArgs e)
{
    if (this.table != null)
        progressBar.Value = this.table.Rows.Count;
}

Когда вы запустите это, ваше приложение будет оставаться отзывчивым во время загрузки, и вы увидите изменение ProgressBar, чтобы отобразить количество загруженных строк. Только в конце (когда вы устанавливаете DataSource в DataGridView) приложение, похоже, "зависает", но я не думаю, что есть способ избежать этого. Вы можете выполнять эту операцию только из основного потока, поэтому неизбежно, что пользовательский интерфейс становится невосприимчивым. Но в моем тесте DataGridView легко обрабатывает строки 300K + примерно за секунду, поэтому это не должно быть большой проблемой.

Ответ 5

1.Загрузить ajax loader.gif из google.

2.Замените это изображение с помощью этого кода.

3. Установите время соответственно.

<div id="spinner" style="display: none;">
<span id="ss" style="float: left; margin-left: 50% !Important; margin-top: 22% !Important;">
<img src="ajax-pink-loader.gif" alt="Loading..." />
</span>
</div>

    $("#ssubmit").click(function () {
        $("#spinner").show();
        setInterval(function () {
            $("#spinner").hide();
        }, 20000);
    });