Почему Form.Refresh () не работает? - PullRequest
1 голос
/ 14 февраля 2010

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

Мне звонят на Form.Refresh() каждый раз, когда я обновляю свои ярлыки / индикаторы выполнения, и он обычно начинает работать. Но если мне когда-нибудь понадобится перейти в режим отладки, просто чтобы немного задержать импорт, вызов Refresh() перестает работать, а иногда, даже если я работаю без режима отладки, в какой-то непредсказуемой точке происходит то же самое: метки и индикаторы выполнения не обновляются, и если вы скрываете форму и снова открываете ее, форма вообще не перерисовывается - она ​​просто отображается полностью белой.

Почему, ну почему Form.Refresh() перестает работать, и как я могу это исправить?

Ответы [ 6 ]

9 голосов
/ 14 февраля 2010

Звучит так, как будто импорт выполняется в потоке пользовательского интерфейса, что означает, что этот поток заблокирован, не позволяя форме перерисовать себя. Лучше было бы использовать компонент BackgroundWorker, выполнить импорт в обработчике событий DoWork и использовать ProgressChanged для обновления пользовательского интерфейса.

Пример:

private void StartImport()
{
    backgroundWorker.WorkerReportsProgress = true;
    backgroundWorker.RunWorkerAsync();
}

private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    // do some work simulating a lenghy process which occasionally
    // reports progress with data back to the caller
    for (int i = 0; i < 100; i++)
    {
        Thread.Sleep(200);
        backgroundWorker.ReportProgress(i, "Item No " + i.ToString());
    }
}

private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    listBox.Items.Add(e.UserState.ToString());
}

При таком подходе вам обычно не нужно вызывать Refresh, чтобы вызвать перерисовку формы.

0 голосов
/ 21 июля 2018

Решение может быть не лучшим решением, но оно определенно подходит для небольших приложений.

В Form1 создайте bool, чтобы проверить, закрыта ли форма.

public bool formclosed = false

Затем в Form2 в обработчике событий закрытия формы добавьте

formclosed = true

также в Form2 после

InitializeComponent(); 

добавить

formclosed = false;

В Form1 создать таймер.

В обработчике timer1.Tick произнесите

    private void timer1_Tick(object sender, EventArgs e)
    {
       if(formclosed == true)
        {
            Application.Restart();
        }
    }

Это перезапустит приложение и обновит все ... У меня также был текст, сохраненный в Properties.Settings.Default, поэтому при каждом запуске приложения показывались настройки по умолчанию.

0 голосов
/ 21 октября 2013

В зависимости от того, какую платформу .NET вы используете, вы можете использовать подход Task.Run:

private void btnShowProgress_Click(object sender, EventArgs e)
{
    progressBar1.Value = 0;

    Task.Run(() =>
    {
        for (int i = 0; i <= 100; i++)
        {
            Thread.Sleep(100);
            progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Value = i; }));                    
        }
    });
}

Task.Run info

Использование invoke с элементами управления

0 голосов
/ 14 февраля 2010

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

Application.DoEvents();
0 голосов
/ 14 февраля 2010

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

Google для некоторых примеров ..

0 голосов
/ 14 февраля 2010

Возможно, вы захотите изменить свой код на использование BeginUpdate и EndUpdate, например:

Control.BeginUpdate();
// Do something to the control, e.g. add items or whatnot
Control.EndUpdate();

Таким образом, обновление не нужно.

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

Редактировать: если форма становится белой, кажется, что код рисования вообще не вызывается, что указывает на то, что он несколько не отвечает.

Я бы проверил код на наличие чего-либо, что может завести в тупик или иным образом зависнуть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...