Files
Shrlalgo.RvKits/ShrlAlgoToolkit.RevitAddins/Windows/ProcessEventHandler.cs
2025-04-24 20:56:44 +08:00

131 lines
4.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using ShrlAlgoToolkit.Core.Assists;
namespace ShrlAlgoToolkit.RevitAddins.Windows
{
class ProcessEventHandler<T> : IExternalEventHandler
{
public ProgressMonitorView ProgressBarView { get; set; }
public ProgressMonitorViewModel ViewModel { get; set; }
public IEnumerable<T> Collection { get; set; }
/// <summary>
/// 附加的参数,用于传额外的变量
/// </summary>
public object AddinParameter { get; set; }
bool Cancel = false;
private readonly ExternalEvent externalEvent;
private readonly Action<UIApplication, T, object> action;
private readonly string transactionName;
private readonly bool useTransaction;
private delegate void ProgressBarDelegate();
public ProcessEventHandler(Action<UIApplication, T, object> action, string transactionName = "处理任务", bool useTransaction = true)
{
externalEvent = ExternalEvent.Create(this);
this.action = action;
this.transactionName = transactionName;
this.useTransaction = useTransaction;
}
public void Execute(UIApplication app)
{
if (app == null)
{
CloseWindow();
return;
}
if (app.ActiveUIDocument == null)
return;
if (app.ActiveUIDocument.Document == null)
return;
if (ProgressBarView == null)
return;
if (ViewModel == null)
return;
Transaction ts = null;
// 根据条件决定是否创建并启动事务
if (useTransaction)
{
ts = new(app.ActiveUIDocument.Document, transactionName);
ts.Start();
}
ProgressBarView.btnCancel.Click += CurrentUI_Closed;
for (ViewModel.CurrentValue = 0; ViewModel.CurrentValue < ViewModel.MaxValue; ViewModel.CurrentValue++)
{
System.Threading.Thread.Sleep(20);
if (Cancel)
break;
var elem = Collection.ElementAt(ViewModel.CurrentValue);
try
{
action(app, elem, AddinParameter);
}
catch(Exception ex)
{
CloseWindow();
// 如果发生异常且事务已启动,则回滚事务
if (useTransaction && ts != null)
{
ts.RollBack();
}
LogAssist.ToLog(ex.Message);
return;
}
//await Task.Delay(50);
//ViewModel.CurrentContext = $"处理 {ViewModel.CurrentValue} / {ViewModel.MaxValue} 完成";
ProgressBarView.Dispatcher.Invoke<string>(() => ViewModel.CurrentContext = $"处理 {ViewModel.CurrentValue} / {ViewModel.MaxValue} 完成", System.Windows.Threading.DispatcherPriority.Background);
//ProgressBarView.Dispatcher.Invoke(ViewModel.NotifyUI, System.Windows.Threading.DispatcherPriority.Background);
}
// 根据条件决定是否提交事务
if (useTransaction && ts != null)
{
//取消的时候,回滚,而不是提交部分处理的事务
if (Cancel)
{
ts.RollBack();
}
else
{
ts.Commit();
}
}
CloseWindow();
// 确保事务对象被正确处理
ts?.Dispose();
}
//private async Task Wait()
//{
// await Task.Delay(50);
//}
private void CloseWindow()
{
ProgressBarView.Closed -= CurrentUI_Closed;
ProgressBarView.Close();
//关闭窗口后需要重设否则同一个外部事件的Cancel会被上次取消过的情况影响
Cancel = false;
}
private void CurrentUI_Closed(object sender, EventArgs e)
{
Cancel = true;
}
public string GetName()
{
return "进度监视";
}
public void Raise()
{
externalEvent.Raise();
}
}
}