用于等待对话框的 C# 线程 UI
好的。我环顾四周,有些人试图将我的用户界面线程化以使其工作。
我有一份报告信息的申请。这是如何工作的,我是一个可以在可滚动区域中重复的用户控件。因此,如果一天有 10 个报告要加载,它将在可滚动区域加载此控件 20 次。
我想要的是在加载这些控件时创建一个“请稍候”对话框。但是,线程 UI 似乎存在问题,因为在绘制这些应位于后面的可滚动区域中的控件时,选取框模式下的进度条不会动画。
尝试在后台工作人员中生成控件,但这并不能解决进度条的问题。
在线程化 UI 绘图方面有什么想法或技巧吗? 我想这就是事实。绘制其他控件时的进度条。
编辑: 我尝试将这个“请稍候”对话框显示为 Show();
和 ShowDialog();
。 ShowDialog() 可以工作,但只是因为它在等待答案时暂停了其余的应用程序。
这是生成控件的代码。这不是背景的线程版本。但唯一的区别是“pleaseWait”对话框在代码中的放置位置。
/// <summary>
/// Generates assignemts after date
/// </summary>
/// <param name="date">Date for selection of what to show</param>
/// <param name="currentWeek">Week to show</param>
/// <param name="igonerWeekCheck">Ignor week check, used for startup</param>
private void GenerateAssigmentsAfterDate(DateTime date, int currentWeek, bool igonerWeekCheck)
{
//refresh UI before generating contens
tabPage1.Refresh();
panelScroller.Refresh();
splitContainer1.Refresh();
//freezes UI while loading
SuspendDrawing(splitContainer1);
panelScroller.SuspendLayout();
if (CurrentTMEngine.LatestWeekNumber != GetWeekNumber(date) || igonerWeekCheck == true)
{
if (igonerWeekCheck == false)
{
pleaseWait = PleaseWaitDialog();
pleaseWait.StartPosition = FormStartPosition.CenterParent;
pleaseWait.Show();
pleaseWait.Update();
}
//should remove current controls from memory
int ctrlCount = panelScroller.Controls.Count;
for (int i = 0; i < ctrlCount; i++)
{
panelScroller.Controls[0].Dispose();
}
panelScroller.Refresh();
assignmentList.Clear();
assignmentList = null;
assignmentList = new List<messageCtrl>();
int rowCountCtrl = 0;
foreach (DataRow row in CurrentTMEngine.TMassignmentsTable.Rows)
{
if (currentWeek == GetWeekNumber(Convert.ToDateTime(row[new TableText().TimeStart]).Date))
{
messageCtrl repCtrl = new messageCtrl(rowCountCtrl, Convert.ToInt32(row[new TableText().ID]),
Convert.ToDateTime(row[new TableText().TimeStart]), Convert.ToDateTime(row[new TableText().TimeEnd]),
panelScroller.Controls, CurrentTMEngine.TMassignmentsTable, row, CurrentTMEngine);
assignmentList.Add(repCtrl);//collection to be avalie for show
rowCountCtrl++;
}
}
foreach (messageCtrl assign in assignmentList)
{
if (currentWeek == GetWeekNumber(assign.StartTime.Date))
{
if (assign.StartTime.Date == date)
{
assign.Enabled = true;
assign.Height = 142;
assign.tableLayoutPanel2.BackColor = System.Drawing.SystemColors.ControlLightLight;
}
else
{
assign.Enabled = false;
assign.Height = 5;
assign.tableLayoutPanel2.BackColor = System.Drawing.SystemColors.ControlDark;
}
panelScroller.Controls.Add(assign); //ands control
}
}
// SetSizeMessageCtrlByDate(date, currentWeek);
pleaseWait.Close();
pleaseWait.Dispose();
}
else
{
SetSizeMessageCtrlByDate(date, currentWeek);
}
CurrentTMEngine.LatestWeekNumber = GetWeekNumber(date);
//unfrezzing UI
panelScroller.ResumeLayout();
ResumeDrawing(splitContainer1);
}
#endregion
EIDT 2: 似乎与UI组件的渲染/绘制有关。当我扩展控制器的可滚动区域以使它们全部适合时,我可以看到这一点。应用程序将冻结,直到 UI 重新绘制为没有滚动条。反之亦然,使滚动尺寸更小。 这似乎是加载控件时发生的冻结类型。所以我想除非有办法拥有多个 UI 线程,否则可能很难找到解决方案,因为它位于同一个应用程序和该应用程序 UI 线程中。
现在问题的解决方案是一个没有动画选框滚动条的“请稍候”对话框。
将检查是否有办法创建一个单独的应用程序来填充这个钱包,因为这似乎是唯一的解决方案。
Ok. I have looked around some tried to thread my UI to make this work.
I have an application for reporting information. How this work is that I a user control that can be repeated in a scrollable area. so If there are 10 reports to load for a day, it will load this control 20 times in the scrollable area.
What I would like is to make a "Please wait" dialog while loading theese controls. But there seems to be a problem to thread UI as a progressbar in Marquee mode wont animate while drawing these controls that should lie in the scrollable area behind.
Have tried to generate the controls in a backgroundworker but that wont solve the problem when it comes to the progressbar.
Any ideas or tips when it come to threading UI drawing?
As I suppose this is what it is. progressbar while drawing other controls.
EDIT:
I tried show this "Please wait" dialog as both Show();
and ShowDialog();
. ShowDialog() works but only becouse it pauses the rest of the applications as it waits for an answer.
Here is the peace of code generating the controls. this is not the threaded version for background. but the only diffrence is where the "pleaseWait" dialog is placed in the code.
/// <summary>
/// Generates assignemts after date
/// </summary>
/// <param name="date">Date for selection of what to show</param>
/// <param name="currentWeek">Week to show</param>
/// <param name="igonerWeekCheck">Ignor week check, used for startup</param>
private void GenerateAssigmentsAfterDate(DateTime date, int currentWeek, bool igonerWeekCheck)
{
//refresh UI before generating contens
tabPage1.Refresh();
panelScroller.Refresh();
splitContainer1.Refresh();
//freezes UI while loading
SuspendDrawing(splitContainer1);
panelScroller.SuspendLayout();
if (CurrentTMEngine.LatestWeekNumber != GetWeekNumber(date) || igonerWeekCheck == true)
{
if (igonerWeekCheck == false)
{
pleaseWait = PleaseWaitDialog();
pleaseWait.StartPosition = FormStartPosition.CenterParent;
pleaseWait.Show();
pleaseWait.Update();
}
//should remove current controls from memory
int ctrlCount = panelScroller.Controls.Count;
for (int i = 0; i < ctrlCount; i++)
{
panelScroller.Controls[0].Dispose();
}
panelScroller.Refresh();
assignmentList.Clear();
assignmentList = null;
assignmentList = new List<messageCtrl>();
int rowCountCtrl = 0;
foreach (DataRow row in CurrentTMEngine.TMassignmentsTable.Rows)
{
if (currentWeek == GetWeekNumber(Convert.ToDateTime(row[new TableText().TimeStart]).Date))
{
messageCtrl repCtrl = new messageCtrl(rowCountCtrl, Convert.ToInt32(row[new TableText().ID]),
Convert.ToDateTime(row[new TableText().TimeStart]), Convert.ToDateTime(row[new TableText().TimeEnd]),
panelScroller.Controls, CurrentTMEngine.TMassignmentsTable, row, CurrentTMEngine);
assignmentList.Add(repCtrl);//collection to be avalie for show
rowCountCtrl++;
}
}
foreach (messageCtrl assign in assignmentList)
{
if (currentWeek == GetWeekNumber(assign.StartTime.Date))
{
if (assign.StartTime.Date == date)
{
assign.Enabled = true;
assign.Height = 142;
assign.tableLayoutPanel2.BackColor = System.Drawing.SystemColors.ControlLightLight;
}
else
{
assign.Enabled = false;
assign.Height = 5;
assign.tableLayoutPanel2.BackColor = System.Drawing.SystemColors.ControlDark;
}
panelScroller.Controls.Add(assign); //ands control
}
}
// SetSizeMessageCtrlByDate(date, currentWeek);
pleaseWait.Close();
pleaseWait.Dispose();
}
else
{
SetSizeMessageCtrlByDate(date, currentWeek);
}
CurrentTMEngine.LatestWeekNumber = GetWeekNumber(date);
//unfrezzing UI
panelScroller.ResumeLayout();
ResumeDrawing(splitContainer1);
}
#endregion
EIDT 2:
Seems to be related to the rendering/drawing of the UI components. I can see this as I expand this scrollable area for the controllers so they all fit. The application freezes until the UI has been redrawn to be with out scrollbar. And vise versa for making it smaller for scroll.
This seems to be the type of freeze that occurs while loading the controls. So I guess unless there is a way to have multiple UI threads it might be hard to find a solution for this as it is located in the same application and this applications UI thread.
Solution for the problem right now is a "Please wait" dialog without a animated Marquee scrollbar.
Will check in to if there is a way to create a separate application for this to fill this purse as that seems to be the only solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您有权访问控件的源代码吗?听起来控件正在使用 UI 线程执行某种后台进程(导致延迟)。不幸的是,只有一个 UI 线程,因此如果它被占用,就会产生停滞效果。
如果您有权访问代码,则可以将其更改为异步加载,以避免出现此问题。如果您无权访问,我能想到的唯一解决方案是启动另一个具有单独 UI 线程的进程(我认为),但这需要创建一个消息框样式窗口。
Do you have access to the source code for the controls? It sounds like the controls are using the UI thread to do some kind of background process (causing the delay). Unfortunately there is only one UI thread, so if it is tied up, you get a stalling effect.
If you have access to the code you could change it to asynchronously load avoiding this issue. If you don't have access the only solution that I can think of would be to launch another process which would have a separate UI thread (I think), however that would requiring creating a message box style window.