c# - 表单没有正确动画
问题描述
在我的应用程序中,我有两个表单(这是我的第一个相当大的应用程序)
单击父表单中的开始按钮后,我希望显示加载面板,并完成一些逻辑。
加载面板(它只是另一个寡妇形式)包含 bunifu 加载圆圈动画(和一些文本)。逻辑部分负责从目录树中收集名称,然后替换树上 Ms.Word 文件中的一些文本。
当我在不执行逻辑的情况下打开加载面板时,加载面板会正确设置动画并且一切正常。
private void bunifuFlatButton1_Click(object sender, EventArgs e)
{
int x = this.Location.X+this.Width/2-75;
int y = this.Location.Y +this.Height/2-175;
Loader_panel LP = new Loader_panel();
LP.Left = x;
LP.Top = y;
LP.Show();
//System.Threading.Thread.Sleep(5000); \\this doesn't help animation to start
if (FormLogic._dataList.Count > 0) \\Here Logic part starts
{
for (int i = 0; i < FormLogic._dataList.Count; i++)
GetDir.GetTarget(FormLogic._dataList[i]);
/*foreach (var directory in FormLogic._dataList)
GetDir.GetTarget(directory);*/
LogList.Items.Add(DateTime.Now + "List isn't empty");// for testing
FormLogic.ClearData();
}
LP.Close();
}
启用逻辑加载面板后出现(外观不流畅),但动画不起作用(它仅在逻辑部分完成工作时才开始工作 - 我通过禁用 LP.Close() 对其进行了测试。这可能是什么原因问题 ?
附加问题。在 .NET 环境中,代码被编译为与多个处理器线程一起工作,还是我必须手动完成?
编辑 06/08/2018 7:21 CEST
我无法从 GetDir 方法访问 LogList(由于其他线程处理它)。我尝试了多个 Invoke 构造,但似乎都不起作用;/我太菜鸟了,无法弄清楚。我在下面的代码中指定了更多细节:
namespace Docr
{
public partial class DocrForm : Form
{
.....
private async void Button1_Click(object sender, EventArgs e)
{
int x = this.Location.X + this.Width / 2 - 75;
int y = this.Location.Y + this.Height / 2 - 175;
Loader_panel LP = new Loader_panel();
LP.Left = x;
LP.Top = y;
LP.Show(); //animation
int count = FormLogic._dataList.Count;
var list = FormLogic._dataList;
await Task.Run(() =>// processing logic during showing animation
{
if (count > 0)
{
for (int i = 0; i < count; i++)
{
GetDir.GetTarget(list[i],LogList); // Passing LogList as and argument
}
Invoke((Action)(() => { LogList.Items.Add(DateTime.Now + "Hi LogList"); }));\\ works fine
}
});
FormLogic.ClearData();
LP.Close();
}
....
}
namespace DocrLogic
{
class GetDir
{
.....
static public void GetTarget(string UserDirectory, ListBox List)// passing ListBox as an Argument
{
var path = UserDirectory;
var TargetDir = new DirectoryInfo(path);
var AllDocs1 = TargetDir.GetFiles("*.doc*", SearchOption.AllDirectories);
var ProperPrefixes = new List<string> { };
Invoke((Action)(() => { List.Items.Add(DateTime.Now + "Hi Log List, GetDir here"); })); // THIS DOESN'T WORK
....
}
.....
}
}
解决方案
您需要制作方法async
,然后使用await
等待逻辑完成。这样 LP 表格就不会被繁重的逻辑打断。
private async void bunifuFlatButton1_Click(object sender, EventArgs e)
{
int x = this.Location.X+this.Width/2-75;
int y = this.Location.Y +this.Height/2-175;
Loader_panel LP = new Loader_panel();
LP.Left = x;
LP.Top = y;
LP.Show();
int count = FormLogic._dataList.Count;
var list = FormLogic._dataList;
await Task.Run(()=>
{
if(count > 0)
{
for (int i = 0; i < count; i++)
{
GetDir.GetTarget(list[i]);
}
this.Invoke(() => { LogList.Items.Add(DateTime.Now + "List isn't empty"); });
}
});
FormLogic.ClearData();
LP.Close();
}
您必须通过使用访问非线程安全对象(例如 UI 对象)来使您的代码线程安全Invoke
,否则,它将抛出 System.Threading.ThreadAbortException 或 System.InvalidOperationException。
调用语法可能因您的项目而异,但您可能会
看到这篇文章以了解正确的使用方法Invoke()
更新
您绝不能尝试在调用之外访问UI 对象。invoke 由System.Windows.Forms.Control
最初创建该控件的线程提供并依赖于该线程。因此在其他一些随机类上调用根本不起作用。
在第二部分中,您需要更改
public static void GetTarget(string UserDirectory, ListBox List)// passing ListBox as an Argument
{
...
Invoke((Action)(() => { List.Items.Add(DateTime.Now + "Hi Log List, GetDir here"); })); // THIS DOESN'T WORK
}
到
(您需要将整个调用行作为操作参数发送)
public static void GetTarget(string UserDirectory, Action action)// passing the action as an Argument
{
...
action();
}
或者
(您需要在开始之前设置Dispatcher
为)LogList
Task
public static Control Dispather;
public static void GetTarget(string UserDirectory)// passing the action as an Argument
{
...
Dispather.Invoke((Action)(() => { List.Items.Add(DateTime.Now + "Hi Log List, GetDir here"); }));
}
推荐阅读
- java - 为什么 Autowired on 无关方法被忽略
- c# - C#如果找不到元素,那么其他的
- python - NameError:遵循教程时未定义全局名称“twitter”
- .net - UWP 自定义按钮弹出
- google-apps-script - 谷歌脚本 getCalendarsByName 返回具有相似名称的日历
- python-3.x - 列表理解以避免创建多个循环
- spring-data-jpa - java.lang.NullPointerException:使用 QueryDsl 过滤数据时
- mysql - 带有 Sequelize 的 Express JS 需要更多时间来执行查询
- mysql - 在 MySQL 中创建过程时出现未知的系统变量
- groovy - 在 Groovy 中,为什么以及如何将 ArrayList 分配给 HashMap 变量?