Mal*_*ist 8 c# windows-vista .net-3.5 progress-bar
我正在使用进度条向用户显示该过程的进度.它有17个步骤,根据天气情况可能需要大约5秒到2到3分钟(好吧,数据库)
我在XP中没有遇到任何问题,进度条没问题,但是在vista中进行测试时我发现情况已经不再如此.
例如:如果它接近5秒,它可能会在消失之前使其成为1/3,因为它已经完成.虽然它的进展是17的17,但它没有显示出来.我相信这是因为动画Vista强加于进度条并且动画无法快速完成.
有谁知道我怎么纠正这个?
这是代码:
这是更新进度条的部分,等待是具有进度条的表单.
int progress = 1;
//1 Cash Receipt Items
waiting.setProgress(progress, 18, progress, "Cash Receipt Items");
tblCashReceiptsApplyToTableAdapter1.Fill(rentalEaseDataSet1.tblCashReceiptsApplyTo);
progress++;
//2 Cash Receipts
waiting.setProgress(progress, "Cash Receipts");
tblCashReceiptsTableAdapter1.Fill(rentalEaseDataSet1.tblCashReceipts);
progress++;
//3 Checkbook Codes
waiting.setProgress(progress, "Checkbook Codes");
tblCheckbookCodeTableAdapter1.Fill(rentalEaseDataSet1.tblCheckbookCode);
progress++;
//4 Checkbook Entries
waiting.setProgress(progress, "Checkbook Entries");
tblCheckbookEntryTableAdapter1.Fill(rentalEaseDataSet1.tblCheckbookEntry);
progress++;
//5 Checkbooks
waiting.setProgress(progress, "Checkbooks");
tblCheckbookTableAdapter1.Fill(rentalEaseDataSet1.tblCheckbook);
progress++;
//6 Companies
waiting.setProgress(progress, "Companies");
tblCompanyTableAdapter1.Fill(rentalEaseDataSet1.tblCompany);
progress++;
//7 Expenses
waiting.setProgress(progress, "Expenses");
tblExpenseTableAdapter1.Fill(rentalEaseDataSet1.tblExpense);
progress++;
//8 Incomes
waiting.setProgress(progress, "Incomes");
tblIncomeTableAdapter1.Fill(rentalEaseDataSet1.tblIncome);
progress++;
//9 Properties
waiting.setProgress(progress, "Properties");
tblPropertyTableAdapter1.Fill(rentalEaseDataSet1.tblProperty);
progress++;
//10 Rental Units
waiting.setProgress(progress, "Rental Units");
tblRentalUnitTableAdapter1.Fill(rentalEaseDataSet1.tblRentalUnit);
progress++;
//11 Tenant Status Values
waiting.setProgress(progress, "Tenant Status Values");
tblTenantStatusTableAdapter1.Fill(rentalEaseDataSet1.tblTenantStatus);
progress++;
//12 Tenants
waiting.setProgress(progress, "Tenants");
tblTenantTableAdapter1.Fill(rentalEaseDataSet1.tblTenant);
progress++;
//13 Tenant Transaction Codes
waiting.setProgress(progress, "Tenant Transaction Codes");
tblTenantTransCodeTableAdapter1.Fill(rentalEaseDataSet1.tblTenantTransCode);
progress++;
//14 Transactions
waiting.setProgress(progress, "Transactions");
tblTransactionTableAdapter1.Fill(rentalEaseDataSet1.tblTransaction);
progress++;
//15 Vendors
waiting.setProgress(progress, "Vendors");
tblVendorTableAdapter1.Fill(rentalEaseDataSet1.tblVendor);
progress++;
//16 Work Order Categories
waiting.setProgress(progress, "Work Order Categories");
tblWorkOrderCategoryTableAdapter1.Fill(rentalEaseDataSet1.tblWorkOrderCategory);
progress++;
//17 Work Orders
waiting.setProgress(progress, "Work Orders");
tblWorkOrderTableAdapter1.Fill(rentalEaseDataSet1.tblWorkOrder);
progress++;
//18 Stored procs
waiting.setProgress(progress, "Stored Procedures");
getAllCheckbookBalancesTableAdapter1.Fill(rentalEaseDataSet1.GetAllCheckbookBalances);
getAllTenantBalancesTableAdapter1.Fill(rentalEaseDataSet1.GetAllTenantBalances);
//getCheckbookBalanceTableAdapter1;
//getTenantBalanceTableAdapter1;
getTenantStatusID_CurrentTableAdapter1.Fill(rentalEaseDataSet1.GetTenantStatusID_Current);
getTenantStatusID_FutureTableAdapter1.Fill(rentalEaseDataSet1.GetTenantStatusID_Future);
getTenantStatusID_PastTableAdapter1.Fill(rentalEaseDataSet1.GetTenantStatusID_Past);
selectVacantRentalUnitsByIDTableAdapter1.Fill(rentalEaseDataSet1.SelectVacantRentalUnitsByID);
getRentBasedBalancesTableAdapter1.Fill(rentalEaseDataSet1.GetRentBasedBalances);
getAgingBalanceTableAdapter2.Fill(rentalEaseDataSet1.GetAgingBalance);
waiting.Close();
Run Code Online (Sandbox Code Playgroud)
这是等待形式:
public partial class PleaseWaitDialog : Form {
public PleaseWaitDialog() {
CheckForIllegalCrossThreadCalls = false;
InitializeComponent();
}
public void setProgress(int current, int max, int min, string loadItem) {
Debug.Assert(min <= max, "Minimum is bigger than the maximum!");
Debug.Assert(current >= min, "The current progress is less than the minimum progress!");
Debug.Assert(current <= max, "The progress is greater than the maximum progress!");
prgLoad.Minimum = min;
prgLoad.Maximum = max;
prgLoad.Value = current;
lblLoadItem.Text = loadItem;
}
public void setProgress(int current, string loadItem) {
this.setProgress(current, prgLoad.Maximum, prgLoad.Minimum, loadItem);
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*own 33
Vista在更新进度条时引入了动画效果 - 它尝试从前一个位置平滑地滚动到新设置的位置,这在控件的更新中产生了令人讨厌的时滞.当您以较大的增量跳过进度条时,滞后最明显,例如在一次跳跃中从25%跳到50%.
正如另一张海报指出的那样,您可以禁用进度条的Vista主题,然后它将模仿XP进度条的行为.
我找到了另一种解决方法:如果你向后设置进度条,它会立即绘制到这个位置.所以,如果你想从25%跳到50%,你会使用(诚然是hackish)逻辑:
progressbar.Value = 50;
progressbar.Value = 49;
progressbar.Value = 50;
Run Code Online (Sandbox Code Playgroud)
我知道,我知道 - 这是一个愚蠢的黑客 - 但它确实有效!
这整个混乱的原因是Vista和W7引入的插值动画效果.它与线程阻塞问题毫无关系.调用setProgress()或driectly设置Value属性会触发动画效果,我将解释如何作弊:
我想出了一个根据固定值设置最大值的黑客.最大属性不会触发效果,因此您可以通过即时响应自由移动进度.
请记住,实际显示的进度由下式给出:ProgressBar.Value/ProgressBar.Maximum.考虑到这一点,下面的例子将把进度从0移到100,由i重新提交:
ProgressBar works like this:
progress = value / maximum
therefore:
maximum = value / progress
Run Code Online (Sandbox Code Playgroud)
我添加了一些所需的缩放因子,应该是自我解释的:
progressBar1.Maximum *= 100;
progressBar1.Value = progressBar1.Maximum / 100;
for (int i = 1; i < 100; i++)
{
progressBar1.Maximum = (int)((double)progressBar1.Value / (double)(i + 1) * 100);
Thread.Sleep(20);
}
Run Code Online (Sandbox Code Playgroud)
尝试调用对该waiting.setProgess()
方法的调用,因为waiting
似乎存在于另一个线程中,这将是一个经典的跨线程调用(如果您允许,编译器会警告您)。
由于Control.Invoke
使用起来有点笨拙,我通常使用扩展方法来传递 lambda 表达式:
waiting.ThreadSafeInvoke(() => waiting.setProgress(...));
Run Code Online (Sandbox Code Playgroud)
。
// also see http://stackoverflow.com/questions/788828/invoke-from-different-thread
public static class ControlExtension
{
public static void ThreadSafeInvoke(this Control control, MethodInvoker method)
{
if (control != null)
{
if (control.InvokeRequired)
{
control.Invoke(method);
}
else
{
method.Invoke();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
18539 次 |
最近记录: |