Не работает прогресс бар типа Marquee. По нажатию кнопку использую код:
progressBar.Visible = true;
progressBar.Style = ProgressBarStyle.Marquee;
progressBar.MarqueeAnimationSpeed = 30;
затем после всех запросов в базу в конце процедуры:
progressBar.Style = ProgressBarStyle.Continuous;
progressBar.MarqueeAnimationSpeed = 0;
progressBar.Visible = false;
Но прогресс бар не работает, хотя везде пишут, что этого достаточно. Окно открывается модально, в котором нажимается кнопку и на форме нарисован прогресс бар.
private void btnOK_Click(object sender, EventArgs e)
{
progressBar.Style = ProgressBarStyle.Marquee;
progressBar.MarqueeAnimationSpeed = 30;
progressBar.Visible = true;
string dt = dtPicker.Value.Date.ToString("dd.MM.yyyy");
string str_item = "";
foreach (object itemChecked in cklstBox.CheckedItems)
{
if (str_item != "")
{
str_item += ", ";
}
str_item += "'" + itemChecked.ToString() + "'";
}
if (str_item == "")
{
MessageBox.Show("Не выбрано ни одной компании!", "Ошибка!",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
this.DialogResult = System.Windows.Forms.DialogResult.None;
return;
}
string sqlForCnt = "SELECT * FROM dbo.Clients WHERE ClientCode IN (" + str_item + ")";
string odbccon = this.ConnectionStr;
string filename = @"5.docx";
SqlConnection _con = new SqlConnection(odbccon);
_con.Open();
DataTable dtb;
//DataSet ds;
SqlDataAdapter adapter;
dtb = new DataTable();
using (adapter = new SqlDataAdapter(sqlForCnt, _con))
{
adapter.Fill(dtb);
}
_con.Close();
foreach (System.Data.DataRow rw in dtb.Rows)
{
try
{
string fName = RiskReportPath + @"\";
if (!Directory.Exists(fName + dt))
{
Directory.CreateDirectory(fName + dt);
}
string fout = fName + dt + @"\" + reportfilename + @".docx";
//здесь идут куча запросов в базу и формирование xml
rtfgen r = new rtfgen(filename, (string)rw[0], dt, klientcode.Replace("_", "").Replace("-", "") + dt.Replace(".", ""), odbccon);
if (File.Exists(fout))
{
File.Delete(fout);
}
r.WriteTo(fout);
progressBar.MarqueeAnimationSpeed = 0;
MessageBox.Show("Отчет по рискам сформирован успешно.", "Отчет по рискам!",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
catch (Exception ex)
{
progressBar.Style = ProgressBarStyle.Continuous;
progressBar.MarqueeAnimationSpeed = 0;
progressBar.Visible = false;
throw ex;
}
}
}
Проблема WinForms, что она "учит" писать жуткую лапшу. Позволю себе пару замечаний. Начнем по порядку.
1) Вот это код проверки чекбоксов
string str_item = "";
foreach (object itemChecked in cklstBox.CheckedItems)
{
if (str_item != "")
{
str_item += ", ";
}
str_item += "'" + itemChecked.ToString() + "'";
}
Лучше переписать как вызов метода и получение результата
string clientCodes = GetClientCodes();
тогда вместо вашего if (str_item == "")
будет проверка такая
if (String.IsNullOrEmpty(clientCodes)) {...}
2) Всю работу по запросам к БД нужно выделять в отдельный класс, а не лепить, так сказать, по месту имения. Создайте отдельный класс Repository
, напишите там всю логику работы с данными в БД (там должны быть методы типа получить всех клиентов public List<Client> GetAllClients()
, сохранить нового клиента public void AddClient(Client client)
и т.д). Тогда в форме будет достаточно создать приватное поле
private readonly Repository _repo;
и в конструкторе формы его проинициализировать
_repo = new Repository();
и далее можно получать и сохранять данные в БД через методы этого класса, например
List<Client> clients = _repo.GetClientsByCodes(clientCodes);
3) Вот в этом цикле foreach (System.Data.DataRow rw in dtb.Rows)
лежит очень злое**** код. Его нужно разбить на отдельные методы. try/catch
должно быть снаружи этого цикла, а не как у вас внутри, надо добавить блок finally
в котором как раз и делать возвращение состояния прогрессбара к исход. состоянию
try
{
foreach (var client in clients)
{
string fout = GetFileName();
if (File.Exists(fout))
{
File.Delete(fout);
}
//!!!Классы нужно именовать правильно, с заглавной буквы, а не как у вас
rtfgen r = new rtfgen(filename,.....
//ну и далее
}
}
catch(...)
{
}
finally
{
progressBar.Style = ProgressBarStyle.Continuous;
progressBar.MarqueeAnimationSpeed = 0;
progressBar.Visible = false;
}
4) Для того, чтобы освободить, не замораживать UI программы нужно использовать async/await
и Task.Run()
. Тогда всю работу с циклом нужно вынести в отдельный метод типа SaveClientsRtf()
и тогда вызывать в блоке try
так
try
{
await Task.Run(() => SaveClientsRtf(clients));
}
catch...finally...
Подробнее как работать с асинхрон. кодом см. пример
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
В общем, есть switch длиной с Эверест, как бы вы избавились от него, кроме как записывать это в Dictionary?
Здравствуйте, подскажите как бы Вы написали следующий функционал, хочу узнать как можно реализовать это более эффективно, спасибо
Доброго времени сутокВ разрабатываемом приложении работа с данными БД происходит через запросы, формируемые следующим образом (например...
Подскажите что это значит (скрин), и какие способы решения есть, и соответственно из-за чего это может происходить ? Используется реклама Kidoz,...