Как я могу сделать бесконечный индикатор выполнения в WinForms?

Я не знаю, сколько времени может занять действие, и я хочу отобразить индикатор выполнения для пользователя в диалоговом окне. Я пытался использовать System.Windows.Forms.ProgressBar, но, похоже, он его не поддерживает.

Примером того, что я хотел бы, является индикатор выполнения, который Windows показывает вам, когда он ищет новые драйверы в Интернете. У него просто есть три или четыре «полосы», идущие вперед и назад в стиле бегущей строки на индикаторе выполнения.

Как я могу это сделать?


person Malfist    schedule 11.03.2009    source источник


Ответы (6)


System.Windows.Forms.ProgressBar имеет свойство с именем Style. Установка Style на Marquee позволит достичь желаемого эффекта.

EDIT: Divo указывает на бегущую строку Стиль доступен только на

Windows XP Home Edition, Windows XP Professional x64 Edition, Windows Server 2003

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

person Mykroft    schedule 11.03.2009
comment
Похоже, Microsoft не может полностью отказаться от выделения. :-Д - person Tomalak; 11.03.2009
comment
Сделайте это Windows XP или выше. Я только что протестировал Windows Vista и Windows 7 Beta (обе 64-разрядные), и это сработало. - person Joey; 11.03.2009
comment
Примечание. Это функция .NET 2.0+. .NET 1.1 не предоставляло свойство стиля. - person Kenneth Cochran; 11.03.2009
comment
Поскольку вопрос помечен .net3.5, я думаю, можно с уверенностью предположить, что спрашивающий не будет пытаться использовать его в .NET 1.1. - person Joey; 12.03.2009

Вы пытались установить для свойства Style System.Windows.Forms.ProgressBar значение Marquee?

Однако неожиданно это свойство доступно только на следующих платформах (согласно MSDN):

Windows XP Home Edition, Windows XP Professional x64 Edition, Windows Server 2003

Возможно, документация не была обновлена ​​до Vista. Кто-нибудь знает об ограничении на Vista?

РЕДАКТИРОВАТЬ: Как указано в другом комментарии, документация кажется неправильной в отношении поддерживаемых платформ. Должен работать как на Vista, так и на Windows 7.

person Dirk Vollmar    schedule 11.03.2009

Просто используйте анимированный gif :)

Вы можете сделать свой собственный здесь: http://www.ajaxload.info/

person Chris Lawlor    schedule 11.03.2009

Я нашел решение Криса Лоула лучшим, очень хорошим и чистым решением, просто включите gif http://www.ajaxload.info/ и никакого беспорядка, создающего бесконечный индикатор выполнения.

person NightlyHakr    schedule 17.08.2010
comment
Нет беспорядка, создающего бесконечный индикатор выполнения? Все, что вам нужно сделать, это установить анимацию выделения на 0 после завершения и установить для свойства Visible индикатора выполнения значение false. Это не магия. - person Houman; 07.03.2011

Это то, что сработало для меня. Я создаю для вас неопределенный индикатор прогресса. Добавьте пользовательский элемент управления в свой проект/форму и вставьте этот код:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace AnimatedCustomControls
{
  sealed class IndeterminateProgressbar : Control
  {
    private readonly List<int> positions = new List<int>();
    private readonly Timer tmrAnimation = new Timer {Interval = 5, Enabled = false};
    private readonly Timer tmrAddPosition = new Timer {Interval = 500, Enabled = true};


    public Color ProgressColor { get; set; }
    public Color InactiveColor { get; set; }

    public IndeterminateProgressbar()
    {
        DoubleBuffered = true;
        SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
        ProgressColor = Color.FromArgb(40, 190, 245);
        InactiveColor = Color.FromArgb(40, 40, 40);
        tmrAnimation.Tick += tmrAnimation_Tick;
        tmrAddPosition.Tick += tmrAddPosition_Tick;
        if (!DesignMode) tmrAnimation.Start();
    }

    void tmrAddPosition_Tick(object sender, EventArgs e)
    {
        positions.Add(1);
    }

    void tmrAnimation_Tick(object sender, EventArgs e)
    {
        if (DesignMode) tmrAnimation.Stop();
        for (int i = 0; i < positions.Count; i++)
        {
            positions[i] += 2 + Math.Abs(positions[i]) / 50;
            if (positions[i] > Width) positions.RemoveAt(i);
        }
        Invalidate();
    }

    protected override void OnEnabledChanged(EventArgs e)
    {
        base.OnEnabledChanged(e);
        if (Enabled)
        {
            positions.Clear();
            positions.AddRange(new[] { Width / 10, Width / 3, Width / 2, (int)(Width * 0.7) });
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (Enabled)
        {
            e.Graphics.Clear(BackColor);
            foreach (int i in positions)
            {
                e.Graphics.DrawLine(new Pen(Brushes.Black, 4f), i, 0, i, Height);
            }
        }
        else e.Graphics.Clear(InactiveColor);

        base.OnPaint(e);
    }
}

}

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

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

        private void Form1_Load(object sender, EventArgs e)
    {
        indeterminateProgressbar1.BackColor = Color.FromArgb(40, 190, 245); //it's an nice color ;)
        indeterminateProgressbar1.Size = new Size(400, 4); //make it small in the height looks better
        indeterminateProgressbar1.Visible = true;
    }
person Colyn Jonker    schedule 30.04.2014

Может быть лучший способ, но один из способов — просто установить значение обратно на 0, когда оно достигнет конца (при условии, что ваша задача не завершена)

person Davy8    schedule 11.03.2009
comment
Я чувствую физическую боль каждый раз, когда вижу, как это делает программа. С точки зрения юзабилити это одна из худших вещей, которые может сделать ленивый программист. Это неинформативно, неправильно, отвлекает, раздражает и снижает доверие пользователя к метафоре индикатора выполнения в целом. Даже лучше вообще без индикатора прогресса. - person Tomalak; 11.03.2009
comment
Согласовано. Вероятно, лучшим решением для длительного процесса, для которого невозможно получить информацию о ходе выполнения (вопрос был немного неясен), было бы вообще отсутствие индикатора выполнения... но, эй, он спросил, как получить неопределенный: ) - person Joey; 11.03.2009
comment
Похоже, я неправильно понял желаемый эффект. Это был единственный бесконечный индикатор прогресса, который я мог вспомнить навскидку. - person Davy8; 11.03.2009
comment
Отсутствие индикатора выполнения определенно хуже, если оно будет длинным (скажем, более 10-30 секунд, в зависимости от терпения человека и от того, насколько медленным, по его мнению, будет его компьютер. Обычно я рассматриваю возможность уничтожения процесса после 30 секунд отсутствия индикации прогресса. - person Davy8; 11.03.2009
comment
@ Davy8: Мне всегда нравилась идея логотипа (то есть абстракции аналоговых часов), который немного вращается, когда что-то происходит (событие копирования файла или что-то подобное). Если происходит много событий, он вращается быстро, если мало, он вращается медленно. Если процесс мертв, он вообще не вращается. - person Tomalak; 11.03.2009
comment
Также никакие индикаторы прогресса не равны никаким признакам того, что идентификатор процесса что-то делает. Вы по-прежнему можете переключить курсор на занятый, сообщить пользователю, что вы делаете, и т. д. Но индикатор выполнения — не идеальная идиома, если у вас есть процесс, в котором вы не можете оценить завершение или прогресс. - person Joey; 12.03.2009