增加进度对话框

This commit is contained in:
ww-rm
2025-02-27 13:42:11 +08:00
parent cf1056d1d6
commit a6978e2bfe
7 changed files with 403 additions and 58 deletions

View File

@@ -30,6 +30,7 @@
{
panel = new Panel();
tableLayoutPanel1 = new TableLayoutPanel();
label4 = new Label();
label3 = new Label();
comboBox_Version = new ComboBox();
tableLayoutPanel2 = new TableLayoutPanel();
@@ -39,7 +40,6 @@
button_SelectSkel = new Button();
label_Tip = new Label();
openFileDialog_Skel = new OpenFileDialog();
label4 = new Label();
panel.SuspendLayout();
tableLayoutPanel1.SuspendLayout();
tableLayoutPanel2.SuspendLayout();
@@ -79,6 +79,19 @@
tableLayoutPanel1.Size = new Size(1026, 424);
tableLayoutPanel1.TabIndex = 1;
//
// label4
//
label4.AutoSize = true;
tableLayoutPanel1.SetColumnSpan(label4, 4);
label4.Dock = DockStyle.Fill;
label4.Location = new Point(15, 15);
label4.Margin = new Padding(15);
label4.Name = "label4";
label4.Size = new Size(996, 24);
label4.TabIndex = 14;
label4.Text = "说明批量导入只需要选择skel文件atlas文件需要在同目录下并且与skel文件名相同";
label4.TextAlign = ContentAlignment.MiddleCenter;
//
// label3
//
label3.Anchor = AnchorStyles.Right;
@@ -147,6 +160,7 @@
tableLayoutPanel1.SetColumnSpan(listBox_FilePath, 2);
listBox_FilePath.Dock = DockStyle.Fill;
listBox_FilePath.FormattingEnabled = true;
listBox_FilePath.HorizontalScrollbar = true;
listBox_FilePath.ItemHeight = 24;
listBox_FilePath.Location = new Point(3, 97);
listBox_FilePath.Name = "listBox_FilePath";
@@ -182,19 +196,6 @@
openFileDialog_Skel.Filter = "skel 文件 (*.skel; *.json)|*.skel;*.json";
openFileDialog_Skel.Multiselect = true;
//
// label4
//
label4.AutoSize = true;
tableLayoutPanel1.SetColumnSpan(label4, 4);
label4.Dock = DockStyle.Fill;
label4.Location = new Point(15, 15);
label4.Margin = new Padding(15);
label4.Name = "label4";
label4.Size = new Size(996, 24);
label4.TabIndex = 14;
label4.Text = "说明批量导入只需要选择skel文件atlas文件需要在同目录下并且与skel文件名相同";
label4.TextAlign = ContentAlignment.MiddleCenter;
//
// BatchOpenSpineDialog
//
AcceptButton = button_Ok;

View File

@@ -87,7 +87,7 @@
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_File, toolStripMenuItem_Help });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(1519, 32);
menuStrip.Size = new Size(1741, 32);
menuStrip.TabIndex = 0;
menuStrip.Text = "菜单";
//
@@ -162,7 +162,7 @@
rtbLog.Margin = new Padding(3, 2, 3, 2);
rtbLog.Name = "rtbLog";
rtbLog.ReadOnly = true;
rtbLog.Size = new Size(1499, 102);
rtbLog.Size = new Size(1721, 159);
rtbLog.TabIndex = 0;
rtbLog.Text = "";
rtbLog.WordWrap = false;
@@ -184,8 +184,8 @@
//
splitContainer_MainForm.Panel2.Controls.Add(rtbLog);
splitContainer_MainForm.Panel2.Cursor = Cursors.Default;
splitContainer_MainForm.Size = new Size(1499, 838);
splitContainer_MainForm.SplitterDistance = 732;
splitContainer_MainForm.Size = new Size(1721, 958);
splitContainer_MainForm.SplitterDistance = 795;
splitContainer_MainForm.TabIndex = 3;
splitContainer_MainForm.TabStop = false;
splitContainer_MainForm.SplitterMoved += splitContainer_SplitterMoved;
@@ -207,8 +207,8 @@
//
splitContainer_Functional.Panel2.Controls.Add(groupBox_Preview);
splitContainer_Functional.Panel2.Cursor = Cursors.Default;
splitContainer_Functional.Size = new Size(1499, 732);
splitContainer_Functional.SplitterDistance = 698;
splitContainer_Functional.Size = new Size(1721, 795);
splitContainer_Functional.SplitterDistance = 725;
splitContainer_Functional.TabIndex = 2;
splitContainer_Functional.TabStop = false;
splitContainer_Functional.SplitterMoved += splitContainer_SplitterMoved;
@@ -230,8 +230,8 @@
//
splitContainer_Information.Panel2.Controls.Add(splitContainer_Config);
splitContainer_Information.Panel2.Cursor = Cursors.Default;
splitContainer_Information.Size = new Size(698, 732);
splitContainer_Information.SplitterDistance = 336;
splitContainer_Information.Size = new Size(725, 795);
splitContainer_Information.SplitterDistance = 346;
splitContainer_Information.TabIndex = 1;
splitContainer_Information.TabStop = false;
splitContainer_Information.SplitterMoved += splitContainer_SplitterMoved;
@@ -243,7 +243,7 @@
groupBox_SkelList.Dock = DockStyle.Fill;
groupBox_SkelList.Location = new Point(0, 0);
groupBox_SkelList.Name = "groupBox_SkelList";
groupBox_SkelList.Size = new Size(336, 732);
groupBox_SkelList.Size = new Size(346, 795);
groupBox_SkelList.TabIndex = 0;
groupBox_SkelList.TabStop = false;
groupBox_SkelList.Text = "模型列表";
@@ -254,7 +254,7 @@
spineListView.Location = new Point(3, 26);
spineListView.Name = "spineListView";
spineListView.PropertyGrid = propertyGrid_Skel;
spineListView.Size = new Size(330, 703);
spineListView.Size = new Size(340, 766);
spineListView.TabIndex = 0;
//
// propertyGrid_Skel
@@ -263,7 +263,7 @@
propertyGrid_Skel.HelpVisible = false;
propertyGrid_Skel.Location = new Point(3, 26);
propertyGrid_Skel.Name = "propertyGrid_Skel";
propertyGrid_Skel.Size = new Size(352, 464);
propertyGrid_Skel.Size = new Size(369, 506);
propertyGrid_Skel.TabIndex = 0;
propertyGrid_Skel.ToolbarVisible = false;
//
@@ -284,8 +284,8 @@
//
splitContainer_Config.Panel2.Controls.Add(groupBox_PreviewConfig);
splitContainer_Config.Panel2.Cursor = Cursors.Default;
splitContainer_Config.Size = new Size(358, 732);
splitContainer_Config.SplitterDistance = 493;
splitContainer_Config.Size = new Size(375, 795);
splitContainer_Config.SplitterDistance = 535;
splitContainer_Config.TabIndex = 0;
splitContainer_Config.TabStop = false;
splitContainer_Config.SplitterMoved += splitContainer_SplitterMoved;
@@ -297,7 +297,7 @@
groupBox_SkelConfig.Dock = DockStyle.Fill;
groupBox_SkelConfig.Location = new Point(0, 0);
groupBox_SkelConfig.Name = "groupBox_SkelConfig";
groupBox_SkelConfig.Size = new Size(358, 493);
groupBox_SkelConfig.Size = new Size(375, 535);
groupBox_SkelConfig.TabIndex = 0;
groupBox_SkelConfig.TabStop = false;
groupBox_SkelConfig.Text = "模型参数";
@@ -307,7 +307,7 @@
groupBox_PreviewConfig.Dock = DockStyle.Fill;
groupBox_PreviewConfig.Location = new Point(0, 0);
groupBox_PreviewConfig.Name = "groupBox_PreviewConfig";
groupBox_PreviewConfig.Size = new Size(358, 235);
groupBox_PreviewConfig.Size = new Size(375, 256);
groupBox_PreviewConfig.TabIndex = 1;
groupBox_PreviewConfig.TabStop = false;
groupBox_PreviewConfig.Text = "画面参数";
@@ -318,7 +318,7 @@
groupBox_Preview.Dock = DockStyle.Fill;
groupBox_Preview.Location = new Point(0, 0);
groupBox_Preview.Name = "groupBox_Preview";
groupBox_Preview.Size = new Size(797, 732);
groupBox_Preview.Size = new Size(992, 795);
groupBox_Preview.TabIndex = 1;
groupBox_Preview.TabStop = false;
groupBox_Preview.Text = "预览画面";
@@ -330,7 +330,7 @@
panel_PreviewContainer.Location = new Point(3, 26);
panel_PreviewContainer.Margin = new Padding(0);
panel_PreviewContainer.Name = "panel_PreviewContainer";
panel_PreviewContainer.Size = new Size(791, 703);
panel_PreviewContainer.Size = new Size(986, 766);
panel_PreviewContainer.TabIndex = 1;
//
// panel_Preview
@@ -348,7 +348,7 @@
panel_MainForm.Location = new Point(0, 32);
panel_MainForm.Name = "panel_MainForm";
panel_MainForm.Padding = new Padding(10, 5, 10, 10);
panel_MainForm.Size = new Size(1519, 853);
panel_MainForm.Size = new Size(1741, 973);
panel_MainForm.TabIndex = 4;
//
// openFileDialog_Skel
@@ -367,7 +367,7 @@
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1519, 885);
ClientSize = new Size(1741, 1005);
Controls.Add(panel_MainForm);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;

137
SpineViewer/src/ProgressDialog.Designer.cs generated Normal file
View File

@@ -0,0 +1,137 @@
namespace SpineViewer
{
partial class ProgressDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
progressBar = new ProgressBar();
panel1 = new Panel();
tableLayoutPanel1 = new TableLayoutPanel();
button_Cancel = new Button();
label_Tip = new Label();
backgroundWorker = new System.ComponentModel.BackgroundWorker();
panel1.SuspendLayout();
tableLayoutPanel1.SuspendLayout();
SuspendLayout();
//
// progressBar
//
progressBar.Dock = DockStyle.Fill;
progressBar.Location = new Point(3, 57);
progressBar.Name = "progressBar";
progressBar.Size = new Size(552, 34);
progressBar.Style = ProgressBarStyle.Continuous;
progressBar.TabIndex = 0;
//
// panel1
//
panel1.Controls.Add(tableLayoutPanel1);
panel1.Dock = DockStyle.Fill;
panel1.Location = new Point(0, 0);
panel1.Name = "panel1";
panel1.Padding = new Padding(30);
panel1.Size = new Size(618, 206);
panel1.TabIndex = 1;
//
// tableLayoutPanel1
//
tableLayoutPanel1.ColumnCount = 1;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.Controls.Add(progressBar, 0, 1);
tableLayoutPanel1.Controls.Add(button_Cancel, 0, 2);
tableLayoutPanel1.Controls.Add(label_Tip, 0, 0);
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.Location = new Point(30, 30);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 3;
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.Size = new Size(558, 146);
tableLayoutPanel1.TabIndex = 1;
//
// button_Cancel
//
button_Cancel.Anchor = AnchorStyles.Bottom;
button_Cancel.Location = new Point(223, 109);
button_Cancel.Margin = new Padding(3, 15, 3, 3);
button_Cancel.Name = "button_Cancel";
button_Cancel.Size = new Size(112, 34);
button_Cancel.TabIndex = 9;
button_Cancel.Text = "取消";
button_Cancel.UseVisualStyleBackColor = true;
button_Cancel.Click += button_Cancel_Click;
//
// label_Tip
//
label_Tip.AutoSize = true;
label_Tip.Dock = DockStyle.Fill;
label_Tip.Location = new Point(3, 10);
label_Tip.Margin = new Padding(3, 10, 3, 10);
label_Tip.Name = "label_Tip";
label_Tip.Size = new Size(552, 34);
label_Tip.TabIndex = 10;
label_Tip.Text = "正在处理 34/100";
//
// backgroundWorker
//
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.WorkerSupportsCancellation = true;
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
//
// ProgressDialog
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(618, 206);
ControlBox = false;
Controls.Add(panel1);
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false;
MinimizeBox = false;
Name = "ProgressDialog";
ShowIcon = false;
ShowInTaskbar = false;
StartPosition = FormStartPosition.CenterScreen;
Text = "进度";
panel1.ResumeLayout(false);
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
ResumeLayout(false);
}
#endregion
private ProgressBar progressBar;
private Panel panel1;
private TableLayoutPanel tableLayoutPanel1;
private System.ComponentModel.BackgroundWorker backgroundWorker;
private Label label_Tip;
private Button button_Cancel;
}
}

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SpineViewer
{
public partial class ProgressDialog : Form
{
[Category("自定义"), Description("BackgroundWorker 的 DoWork 事件")]
public event DoWorkEventHandler? Dowork
{
add { backgroundWorker.DoWork += value; }
remove { backgroundWorker.DoWork -= value; }
}
public void RunWorkerAsync() { backgroundWorker.RunWorkerAsync(); }
public void RunWorkerAsync(object? argument) { backgroundWorker.RunWorkerAsync(argument); }
public ProgressDialog()
{
InitializeComponent();
}
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label_Tip.Text = e.UserState as string;
progressBar.Value = e.ProgressPercentage;
}
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
Program.Logger.Error(e.Error.ToString());
MessageBox.Show(e.Error.Message, "执行出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
DialogResult = DialogResult.Abort;
}
else if (e.Cancelled)
{
DialogResult = DialogResult.Cancel;
}
else
{
DialogResult= DialogResult.OK;
}
}
private void button_Cancel_Click(object sender, EventArgs e)
{
backgroundWorker.CancelAsync();
button_Cancel.Enabled = false;
}
}
}

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="backgroundWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@@ -136,53 +136,53 @@ namespace SpineViewer.Spine
/// 获取所属版本
/// </summary>
[TypeConverter(typeof(VersionTypeConverter))]
[Browsable(true), Category("基本信息"), DisplayName("版本")]
[Category("基本信息"), DisplayName("版本")]
public Version Version { get; }
/// <summary>
/// skel 文件完整路径
/// </summary>
[Browsable(true), Category("基本信息"), DisplayName("skel文件路径")]
[Category("基本信息"), DisplayName("skel文件路径")]
public string SkelPath { get; }
/// <summary>
/// atlas 文件完整路径
/// </summary>
[Browsable(true), Category("基本信息"), DisplayName("atlas文件路径")]
[Category("基本信息"), DisplayName("atlas文件路径")]
public string AtlasPath { get; }
[Browsable(true), Category("基本信息"), DisplayName("名称")]
[Category("基本信息"), DisplayName("名称")]
public string Name { get; }
/// <summary>
/// 缩放比例
/// </summary>
[Browsable(true), Category("空间变换"), DisplayName("缩放比例")]
[Category("空间变换"), DisplayName("缩放比例")]
public abstract float Scale { get; set; }
/// <summary>
/// 位置
/// </summary>
[TypeConverter(typeof(PointFTypeConverter))]
[Browsable(true), Category("空间变换"), DisplayName("位置")]
[Category("空间变换"), DisplayName("位置")]
public abstract PointF Position { get; set; }
/// <summary>
/// 水平翻转
/// </summary>
[Browsable(true), Category("空间变换"), DisplayName("水平翻转")]
[Category("空间变换"), DisplayName("水平翻转")]
public abstract bool FlipX { get; set; }
/// <summary>
/// 垂直翻转
/// </summary>
[Browsable(true), Category("空间变换"), DisplayName("垂直翻转")]
[Category("空间变换"), DisplayName("垂直翻转")]
public abstract bool FlipY { get; set; }
/// <summary>
/// 是否使用预乘Alpha
/// </summary>
[Browsable(true), Category("其他"), DisplayName("预乘Alpha通道")]
[Category("其他"), DisplayName("预乘Alpha通道")]
public bool UsePremultipliedAlpha { get; set; }
/// <summary>
@@ -202,7 +202,7 @@ namespace SpineViewer.Spine
/// 当前动画名称
/// </summary>
[TypeConverter(typeof(AnimationTypeConverter))]
[Browsable(true), Category("其他"), DisplayName("当前播放动画"), PropertyTab()]
[Category("其他"), DisplayName("当前播放动画"), PropertyTab()]
public abstract string CurrentAnimation { get; set; }
/// <summary>

View File

@@ -16,7 +16,7 @@ namespace SpineViewer
{
public partial class SpineListView : UserControl
{
[Browsable(true), Category("自定义"), Description("用于显示骨骼属性的属性页")]
[Category("自定义"), Description("用于显示骨骼属性的属性页")]
public PropertyGrid? PropertyGrid { get; set; }
/// <summary>
@@ -71,40 +71,64 @@ namespace SpineViewer
/// </summary>
public void BatchAdd()
{
var dialog = new BatchOpenSpineDialog();
if (dialog.ShowDialog() != DialogResult.OK)
var openDialog = new BatchOpenSpineDialog();
if (openDialog.ShowDialog() != DialogResult.OK)
return;
int totalCount = dialog.SkelPaths.Length;
int errorCount = 0;
var progressDialog = new ProgressDialog();
progressDialog.Dowork += BatchAdd_Work;
progressDialog.RunWorkerAsync(new { openDialog.SkelPaths, openDialog.Version });
progressDialog.ShowDialog();
}
var version = dialog.Version;
for (int i = 0; i < totalCount; i++)
private void BatchAdd_Work(object? sender, DoWorkEventArgs e)
{
var worker = sender as BackgroundWorker;
var arguments = e.Argument as dynamic;
var skelPaths = arguments.SkelPaths as string[];
var version = (Spine.Version)arguments.Version;
int totalCount = skelPaths.Length;
int success = 0;
int error = 0;
for (int i = 0; i < totalCount; i++)
{
var skelPath = dialog.SkelPaths[i];
Program.Logger.Info("[{}/{}] loading {}", i + 1, totalCount, skelPath);
if (worker.CancellationPending)
break;
var skelPath = skelPaths[i];
worker.ReportProgress((int)((i + 1) * 100.0) / totalCount, $"正在处理 {i + 1}/{totalCount}");
try
{
var spine = Spine.Spine.New(version, skelPath);
spines.Add(spine);
listView.Items.Add(new ListViewItem([spine.Name, spine.Version.String()], -1) { ToolTipText = spine.SkelPath });
if (listView.InvokeRequired)
{
listView.Invoke(() => listView.Items.Add(new ListViewItem([spine.Name, spine.Version.String()], -1) { ToolTipText = spine.SkelPath }));
}
else
{
listView.Items.Add(new ListViewItem([spine.Name, spine.Version.String()], -1) { ToolTipText = spine.SkelPath });
}
success++;
}
catch (Exception ex)
{
Program.Logger.Error(ex.ToString());
Program.Logger.Error("Failed to load {}", skelPath);
errorCount++;
error++;
}
}
if (errorCount > 0)
if (error > 0)
{
Program.Logger.Warn("Batch load {} successfully, {} failed", totalCount - errorCount, errorCount);
MessageBox.Show($"{totalCount - errorCount}成功,{errorCount}失败", "部分骨骼加载失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
Program.Logger.Warn("Batch load {} successfully, {} failed", success, error);
}
else
{
Program.Logger.Info("{} skel loaded successfully", totalCount);
Program.Logger.Info("{} skel loaded successfully", success);
}
}