Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

progress bar design patterns

11 views
Skip to first unread message

Alex Mizrahi

unread,
Sep 15, 2005, 4:15:47 PM9/15/05
to
Hello, All!

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

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

есть какие-нибудь идеи, как реализовать прогресс по-человечески?

With best regards, Alex Mizrahi.


Dmitri Lazarev

unread,
Sep 16, 2005, 1:29:34 AM9/16/05
to
Fri Sep 16 2005 00:15, Alex Mizrahi wrote to All:

AM> From: "Alex Mizrahi" <kill...@matfak.dongu.donetsk.ua>

AM> Hello, All!

AM> задача: есть множество операций типа переписывания файлов и всё такое,
AM> для каждой операции известно сколько она всего занимает (например, байт),
AM> и сколько уже сделано (например, переписано). нужно нарисовать несколько
AM> прогресс-баров относительно некоторых множеств операций.
AM> всё это осложняется тем, что порядок выполнения операций в некоторых
AM> случаях может меняться, в некоторых не может, операции могут
AM> проваливаться и т.д.
AM> ещё есть следующее осложнение -- мы можем планировать что операция займёт
AM> некоторое кол-во единиц, но у функции которая занимается непосредственно
AM> выполнением операции есть свои взгляды на это дело, это надо как-то
AM> учитывать.э

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

AM> есть какие-нибудь идеи, как реализовать прогресс по-человечески?

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

Но в целом насколько я понимаю сделать, чтобы прогрессбар шел ровно, несмотря
на то что внутри совершенно разные операции (например, запись в бд и
копирование файлов), практически нельзя.

WBR, Lazarev Dmitri.

Maxim Friedental

unread,
Sep 15, 2005, 10:31:55 PM9/15/05
to
Hello Alex!


Alex Mizrahi wrote to All:

AM> задача: есть множество операций типа переписывания файлов и всё такое, для
AM> каждой операции известно сколько она всего занимает (например, байт), и
AM> сколько уже сделано (например, переписано). нужно нарисовать несколько


AM> прогресс-баров относительно некоторых множеств операций.

AM> есть какие-нибудь идеи, как реализовать прогресс по-человечески?

Очень просто. Следующий BL объект:

class OperationInfo
{
//Singleton
public static OperationInfo Default {get; set;}

//Registering functions (for BL code implementing operations)
public void Start(string operation, int totalSteps);
public void Step(string operation, optional int steps = 1);
public void Stop(string operation);

//Type declarations for GUI
public event StartEventHandler(int totalSteps);
public event StepEventHandler(int currentProgress);
public event StopEventHandler();

//Reporting functions (for GUI)
public void RegisterForOperation(
string operation,
StartEventHandler onStart,
StepEventHandler onStep,
StopEventHandler onStop);
public int GetTotalSteps(string operation);
public int GetCurrentProgress(string operation);
}

пример BL кода:

ArrayList files = GetFilesToCopy();
OperationInfo.Default.Start("fileCopy", files.Count);
try
{
foreach(string filename in files)
{
File.Copy(filename, filename + "blabla");
OperationInfo.Default.Step("fileCopy", 1);
}
}
finally
{
OperationInfo.Default.Stop("fileCopy");
}

примечание - при необходимости можно добавить еще один параметр в Step - string
message.

Пример GUI кода, работающего на events:

в Init():
OperationInfo.Default.RegisterForOperation("fileCopy", OnStart, OnStep,
OnStop);

public void OnStart(int total)
{
_progressBar.Visible = true;
_progressBar.Max = total;
}
public void OnStep(int currentStep)
{
_progressBar.Val = currentStep;
}
public void OnStop()
{
_progressBar.Visible = false;
}

пример GUI без использования events - вызывать следующий метод три раза в
секунду:
public void UpdateProgress()
{
if(_progressBar.Visible)
{
_progressBar.Val =
OperationInfo.Default.GetCurrentProgress("fileCopy");
}
else
{
if(OperationInfo.Default.GetTotalSteps("fileCopy") > 0)
{
_progressBar.Visible = true;
_progressBar.Max = OperationInfo.Default.GetTotalSteps("fileCopy");
}
}
}

В зависимости от имплементации OperationInfo его можно еще и использовать для
logging.

See you.

0 new messages