调整代码
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
using System.Windows.Media;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Controls
|
||||
{
|
||||
public partial class ColorPickerViewModel : ObservableObject
|
||||
{
|
||||
public ColorPickerViewModel(Color color)
|
||||
{
|
||||
SelectedColor = color;
|
||||
//this.IsActive = true;
|
||||
//WeakReferenceMessenger.Default.Register<ColorPickerViewModel>(this, (r, m) =>
|
||||
//{
|
||||
// // Handle the message here, with r being the recipient and m being the
|
||||
// // input message. Using the recipient passed as input makes it so that
|
||||
// // the lambda expression doesn't capture "this", improving performance.
|
||||
//});
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
public partial Color SelectedColor { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private void Confirm(object obj)
|
||||
{
|
||||
if (obj is System.Windows.Window window)
|
||||
{
|
||||
var colorMessage = new Autodesk.Revit.DB.Color(
|
||||
SelectedColor.R,
|
||||
SelectedColor.G,
|
||||
SelectedColor.B
|
||||
);
|
||||
//发布
|
||||
window.DialogResult = true;
|
||||
WeakReferenceMessenger.Default.Send(colorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<ui:MelWindow
|
||||
Height="390"
|
||||
Icon="{DynamicResource RevitIcon}"
|
||||
Title="颜色设置"
|
||||
Width="340"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
d:DataContext="{d:DesignInstance Type=windows:ColorPickerViewModel}"
|
||||
mc:Ignorable="d"
|
||||
x:Class="ShrlAlgoToolkit.RevitAddins.Common.Controls.ColorPickerWin"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:ShrlAlgoToolkit.RevitAddins.Common.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="https://github.com/ShrlAlgo/Melskin"
|
||||
xmlns:windows="clr-namespace:ShrlAlgoToolkit.RevitAddins.Common.Controls"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Window.Resources>
|
||||
<ResourceDictionary Source="pack://application:,,,/ShrlAlgoToolkit.RevitAddins;component/WPFUI.xaml" />
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<!--<controls:StandardColorPicker
|
||||
x:Name="ColorPicker"
|
||||
Grid.ColumnSpan="2"
|
||||
SelectedColor="{Binding SelectedColor, Delay=25, UpdateSourceTrigger=PropertyChanged}">
|
||||
<b:Interaction.Triggers>
|
||||
<b:EventTrigger EventName="MouseLeftButtonUp">
|
||||
<b:InvokeCommandAction Command="{Binding UpdateColorCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=controls:ColorPicker}}" />
|
||||
</b:EventTrigger>
|
||||
</b:Interaction.Triggers>
|
||||
</controls:StandardColorPicker>-->
|
||||
<ui:ColorPanel
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Grid.Row="0"
|
||||
SelectedColor="{Binding SelectedColor}"
|
||||
x:Name="ColorPicker" />
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
Command="{Binding ConfirmCommand}"
|
||||
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
|
||||
Content="确定" />
|
||||
<Button Command="Close" Content="取消" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ui:MelWindow>
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// ColorPickerWin.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ColorPickerWin
|
||||
{
|
||||
public ColorPickerWin(ColorPickerViewModel viewModel)
|
||||
{
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
24
ShrlAlgoToolkit.RevitAddins/Common/Controls/MessageModel.cs
Normal file
24
ShrlAlgoToolkit.RevitAddins/Common/Controls/MessageModel.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// 错误的条目
|
||||
/// </summary>
|
||||
public class MessageModel
|
||||
{
|
||||
public MessageModel(Element element, string errorMessage)
|
||||
{
|
||||
Element = element;
|
||||
ErrorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public Element Element { get; }
|
||||
|
||||
public object Group { get; set; }
|
||||
|
||||
public bool IsInstance => Element.CanHaveTypeAssigned() && Element.HasPhases();
|
||||
|
||||
public string ErrorMessage { get; }
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Nice3point.Revit.Toolkit.External.Handlers;
|
||||
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Controls;
|
||||
|
||||
public partial class MessageViewModel : ObservableObject
|
||||
{
|
||||
public MessageViewModel(UIDocument uidoc, List<MessageModel> errorModels, string winTitle = "错误处理")
|
||||
{
|
||||
this.uidoc = uidoc;
|
||||
showElementsSectionBox = new ActionEventHandler();
|
||||
ErrorModels.AddRange(errorModels);
|
||||
WinTitle = winTitle;
|
||||
Count = errorModels.Count();
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Footer { get; set; }
|
||||
|
||||
private readonly UIDocument uidoc;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial List<MessageModel> ErrorModels { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string WinTitle { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial int Count { get; set; }
|
||||
|
||||
private readonly ActionEventHandler showElementsSectionBox;
|
||||
[RelayCommand]
|
||||
private void ShowElement(object obj)
|
||||
{
|
||||
if (obj is not MessageModel model)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var doc = uidoc.Document;
|
||||
//if (UiDocument.ActiveView.IsTemporaryHideIsolateActive())
|
||||
//{
|
||||
// UiDocument.ActiveView.temporary
|
||||
//}
|
||||
if (model.Element.IsValidObject)
|
||||
{
|
||||
if (model.Element.IsHidden(uidoc.ActiveView))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ids = new List<ElementId> { model.Element.Id };
|
||||
//UiDocument.ActiveView.IsolateElementTemporary(model.ElementToMove.ViewId);
|
||||
showElementsSectionBox.Raise(
|
||||
_ =>
|
||||
{
|
||||
if (uidoc.ActiveView is not View3D view3d)
|
||||
{
|
||||
view3d = doc.OfClass<View3D>().FirstElement() as View3D;
|
||||
}
|
||||
if (!model.Element.ViewSpecific)
|
||||
{
|
||||
uidoc.ActiveView = view3d;
|
||||
}
|
||||
doc.Invoke(
|
||||
_ =>
|
||||
{
|
||||
if (uidoc.ActiveView is View3D)
|
||||
{
|
||||
view3d.SectionBoxElements(ids);
|
||||
}
|
||||
view3d.ZoomElements(uidoc, ids);
|
||||
uidoc.Selection.SetElementIds(ids);
|
||||
});
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorModels.Remove(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
61
ShrlAlgoToolkit.RevitAddins/Common/Controls/MessageWin.xaml
Normal file
61
ShrlAlgoToolkit.RevitAddins/Common/Controls/MessageWin.xaml
Normal file
@@ -0,0 +1,61 @@
|
||||
<ui:MelWindow
|
||||
Height="450"
|
||||
Icon="{DynamicResource RevitIcon}"
|
||||
Title="{Binding WinTitle}"
|
||||
Width="800"
|
||||
d:DataContext="{d:DesignInstance Type=windows:MessageViewModel}"
|
||||
mc:Ignorable="d"
|
||||
x:Class="ShrlAlgoToolkit.RevitAddins.Common.Controls.MessageWin"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:ShrlAlgoToolkit.RevitAddins.Common.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="https://github.com/ShrlAlgo/Melskin"
|
||||
xmlns:windows="clr-namespace:ShrlAlgoToolkit.RevitAddins.Common.Controls"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Window.Resources>
|
||||
<ResourceDictionary Source="pack://application:,,,/ShrlAlgoToolkit.RevitAddins;component/WPFUI.xaml" />
|
||||
</Window.Resources>
|
||||
<!--<Window.DataContext>
|
||||
<local:ErrorResolveViewModel />
|
||||
</Window.DataContext>-->
|
||||
<ui:StackPanel Margin="5" Spacing="5">
|
||||
<DataGrid
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
IsReadOnly="True"
|
||||
ItemsSource="{Binding ErrorModels}"
|
||||
ToolTip="双击行可快速定位"
|
||||
ui:StackPanel.Fill="Fill">
|
||||
<b:Interaction.Triggers>
|
||||
<b:EventTrigger EventName="MouseDoubleClick">
|
||||
<b:InvokeCommandAction Command="{Binding ShowElementCommand}" CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
|
||||
</b:EventTrigger>
|
||||
</b:Interaction.Triggers>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Binding="{Binding Element.Category.Name}" Header="类别名称" />
|
||||
<DataGridTextColumn Binding="{Binding Element.Name}" Header="元素名称" />
|
||||
<DataGridTextColumn Binding="{Binding Host.Name}" Header="主体" />
|
||||
<DataGridTextColumn Binding="{Binding Element.Id}" Header="元素Id" />
|
||||
<DataGridTextColumn Binding="{Binding ErrorMessage}" Header="错误信息" />
|
||||
<DataGridTemplateColumn Header="操作">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<!-- 按钮参数绑定到当前行的绑定的Item -->
|
||||
<Button
|
||||
Command="{Binding DataContext.ShowElementCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"
|
||||
CommandParameter="{Binding}"
|
||||
Content="定位构件" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<ui:StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||
<ui:Heading Text="注:错误需人处理、或无法处理" ui:StackPanel.Fill="Fill" />
|
||||
<TextBlock Text="{Binding Count, StringFormat=错误数量:{0}}" />
|
||||
<TextBlock Text="{Binding Footer}" />
|
||||
</ui:StackPanel>
|
||||
</ui:StackPanel>
|
||||
</ui:MelWindow>
|
||||
@@ -0,0 +1,15 @@
|
||||
using Melskin.Controls;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// MessageWin.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public sealed partial class MessageWin : MelWindow
|
||||
{
|
||||
public MessageWin()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Controls
|
||||
{
|
||||
public partial class NavigateViewViewModel : ObservableObject
|
||||
{
|
||||
public NavigateViewViewModel(UIApplication uiapp, params Type[] viewTypes)
|
||||
{
|
||||
var doc = uiapp.ActiveUIDocument.Document;
|
||||
Views = doc.OfClasses(viewTypes).Cast<View>().Where(v => !v.IsTemplate).ToList();
|
||||
this.uiapp = uiapp;
|
||||
}
|
||||
|
||||
private readonly UIApplication uiapp;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial IList<View> Views { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private void NavigateView(object obj)
|
||||
{
|
||||
if (obj is View view)
|
||||
{
|
||||
var uidoc = uiapp.ActiveUIDocument;
|
||||
uidoc.ActiveView = view;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<ui:MelWindow
|
||||
Height="200"
|
||||
Icon="{DynamicResource RevitIcon}"
|
||||
Title="选择视图"
|
||||
Width="300"
|
||||
d:DataContext="{d:DesignInstance Type=windows:NavigateViewViewModel}"
|
||||
mc:Ignorable="d"
|
||||
x:Class="ShrlAlgoToolkit.RevitAddins.Common.Controls.NavigateViewWin"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:ShrlAlgoToolkit.RevitAddins.Common.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="https://github.com/ShrlAlgo/Melskin"
|
||||
xmlns:windows="clr-namespace:ShrlAlgoToolkit.RevitAddins.Common.Controls"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Window.Resources>
|
||||
<ResourceDictionary Source="pack://application:,,,/ShrlAlgoToolkit.RevitAddins;component/WPFUI.xaml" />
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<ListBox DisplayMemberPath="Name" ItemsSource="{Binding Views}">
|
||||
<b:Interaction.Triggers>
|
||||
<b:EventTrigger EventName="MouseDoubleClick">
|
||||
<b:InvokeCommandAction Command="{Binding NavigateViewCommand}" CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}" />
|
||||
</b:EventTrigger>
|
||||
</b:Interaction.Triggers>
|
||||
</ListBox>
|
||||
</Grid>
|
||||
</ui:MelWindow>
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// NavigateViewWin.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class NavigateViewWin
|
||||
{
|
||||
public NavigateViewWin(NavigateViewViewModel viewModel)
|
||||
{
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Controls
|
||||
{
|
||||
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();
|
||||
}
|
||||
Common.Assists.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Controls
|
||||
{
|
||||
class ProgressBarManager<T>
|
||||
{
|
||||
private readonly UIDocument uidoc;
|
||||
private readonly IEnumerable<T> collection;
|
||||
private readonly object addinParameter;
|
||||
private readonly Action<UIDocument, T, object> action;
|
||||
private readonly string taskName;
|
||||
private readonly bool useTransaction;
|
||||
ProgressMonitorViewModel viewModel;
|
||||
ProgressMonitorView progressBarView;
|
||||
|
||||
#region 非模态处理
|
||||
private readonly ProcessEventHandler<T> progressEventHandler;
|
||||
/// <summary>
|
||||
/// 非模态进度条,只能开启一次,请勿在遍历中使用
|
||||
/// </summary>
|
||||
/// <param name="progressEventHandler"></param>
|
||||
/// <param name="collection"></param>
|
||||
public ProgressBarManager(ProcessEventHandler<T> progressEventHandler, IEnumerable<T> collection, string taskName = "处理任务", object addinParameter = null)
|
||||
{
|
||||
this.progressEventHandler = progressEventHandler;
|
||||
progressEventHandler.Collection = collection;
|
||||
progressEventHandler.AddinParameter = addinParameter;
|
||||
this.collection = collection;
|
||||
this.taskName = taskName;
|
||||
}
|
||||
public void ProgressModeless()
|
||||
{
|
||||
if (!progressEventHandler.Collection.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
viewModel = new()
|
||||
{
|
||||
MaxValue = collection.Count(),
|
||||
Title = taskName
|
||||
};
|
||||
|
||||
progressBarView ??= new();
|
||||
//progressBarView = ProgressMonitorView.Instance;
|
||||
progressBarView.DataContext = viewModel;
|
||||
progressBarView.Loaded += CurrentUI_ContentRendered;
|
||||
progressBarView.Closed += CurrentUI_Closed;
|
||||
progressBarView.Topmost = true;
|
||||
//progressEventHandler = new(collection, action)
|
||||
//{
|
||||
// ProgressBarView = progressBarView,
|
||||
// ViewModel = viewModel
|
||||
//};
|
||||
if (collection.Any())
|
||||
{
|
||||
progressEventHandler.ProgressBarView = progressBarView;
|
||||
progressEventHandler.ViewModel = viewModel;
|
||||
//progressBarView.Show();
|
||||
progressBarView.Show();
|
||||
//progressEventHandler.Raise();
|
||||
}
|
||||
|
||||
}
|
||||
private void CurrentUI_ContentRendered(object sender, EventArgs e)
|
||||
{
|
||||
progressEventHandler.Raise();
|
||||
}
|
||||
#endregion
|
||||
#region 模态处理
|
||||
bool Cancel { get; set; }
|
||||
//private delegate void ProgressBarDelegate();
|
||||
/// <summary>
|
||||
/// 模态进度条
|
||||
/// </summary>
|
||||
/// <param name="uidoc"></param>
|
||||
/// <param name="collection"></param>
|
||||
/// <param name="action"></param>
|
||||
public ProgressBarManager(UIDocument uidoc, ICollection<T> collection, Action<UIDocument, T, object> action, string taskName = "处理任务", bool useTransaction = true, object addinParameter = null)
|
||||
{
|
||||
this.uidoc = uidoc;
|
||||
this.collection = collection;
|
||||
this.addinParameter = addinParameter;
|
||||
this.action = action;
|
||||
this.taskName = taskName;
|
||||
this.useTransaction = useTransaction;
|
||||
}
|
||||
public void ProgressModal()
|
||||
{
|
||||
if (!collection.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
viewModel = new ProgressMonitorViewModel
|
||||
{
|
||||
MaxValue = collection.Count(),
|
||||
Title = taskName
|
||||
};
|
||||
progressBarView = new ProgressMonitorView
|
||||
{
|
||||
DataContext = viewModel
|
||||
};
|
||||
//progressBarView = ProgressMonitorView.Instance;
|
||||
//progressBarView.DataContext = viewModel;
|
||||
progressBarView.Closed += CurrentUI_Closed;
|
||||
progressBarView.ContentRendered += FireUPModal;
|
||||
|
||||
progressBarView.ShowDialog();
|
||||
}
|
||||
private async void FireUPModal(object sender, EventArgs e)
|
||||
{
|
||||
progressBarView.ContentRendered -= FireUPModal;
|
||||
Transaction ts = null;
|
||||
// 根据条件决定是否创建并启动事务
|
||||
if (useTransaction)
|
||||
{
|
||||
ts = new Transaction(uidoc.Document, taskName);
|
||||
ts.Start();
|
||||
}
|
||||
for (viewModel.CurrentValue = 0; viewModel.CurrentValue < viewModel.MaxValue; viewModel.CurrentValue++)
|
||||
{
|
||||
if (Cancel)
|
||||
break;
|
||||
|
||||
//System.Threading.Thread.Sleep(50);
|
||||
|
||||
try
|
||||
{
|
||||
var t = collection.ElementAt(viewModel.CurrentValue);
|
||||
//Debug.WriteLine(ViewModel.CurrentValue);
|
||||
action(uidoc, t, addinParameter);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
CloseWindow();
|
||||
// 如果发生异常且事务已启动,则回滚事务
|
||||
if (useTransaction && ts != null && ts.GetStatus() == TransactionStatus.Started)
|
||||
{
|
||||
ts.RollBack();
|
||||
}
|
||||
}
|
||||
viewModel.CurrentContext = $"处理 {viewModel.CurrentValue} / {viewModel.MaxValue} 完成";
|
||||
await Task.Delay(50);
|
||||
//progressBarView.Dispatcher.Invoke(viewModel.NotifyUI, System.Windows.Threading.DispatcherPriority.Background);
|
||||
}
|
||||
// 根据条件决定是否提交事务
|
||||
if (useTransaction && ts != null)
|
||||
{
|
||||
ts.Commit();
|
||||
}
|
||||
|
||||
CloseWindow();
|
||||
// 确保事务对象被正确处理
|
||||
ts?.Dispose();
|
||||
}
|
||||
|
||||
private void CloseWindow()
|
||||
{
|
||||
progressBarView.Closed -= CurrentUI_Closed;
|
||||
progressBarView.Close();
|
||||
}
|
||||
|
||||
private void CurrentUI_Closed(object sender, EventArgs e)
|
||||
{
|
||||
Cancel = true;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<Window
|
||||
x:Class="ShrlAlgoToolkit.RevitAddins.Common.Controls.ProgressMonitorView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls1="clr-namespace:ShrlAlgoToolkit.RevitAddins.Common.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:windows="clr-namespace:ShrlAlgoToolkit.RevitAddins.Common.Controls"
|
||||
Title="{Binding Title}"
|
||||
d:DataContext="{d:DesignInstance Type=windows:ProgressMonitorViewModel}"
|
||||
Background="{DynamicResource MaterialDesign.Brush.Background}"
|
||||
Icon="{DynamicResource RevitIcon}"
|
||||
ResizeMode="NoResize"
|
||||
SizeToContent="WidthAndHeight"
|
||||
TextElement.Foreground="{DynamicResource MaterialDesign.Brush.Foreground}"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
mc:Ignorable="d">
|
||||
<Window.Resources>
|
||||
<ResourceDictionary Source="pack://application:,,,/ShrlAlgoToolkit.RevitAddins;component/WPFUI.xaml" />
|
||||
</Window.Resources>
|
||||
<StackPanel Margin="10">
|
||||
<TextBlock Text="{Binding CurrentContext}" />
|
||||
<Separator />
|
||||
<ProgressBar
|
||||
Width="300"
|
||||
Height="23"
|
||||
Maximum="{Binding MaxValue}"
|
||||
Value="{Binding CurrentValue}" />
|
||||
<Separator />
|
||||
<Button
|
||||
x:Name="btnCancel"
|
||||
HorizontalAlignment="Right"
|
||||
Content="取消"
|
||||
IsCancel="True" />
|
||||
</StackPanel>
|
||||
</Window>
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ProgressMonitorView.xaml
|
||||
/// </summary>
|
||||
public partial class ProgressMonitorView : Window
|
||||
{
|
||||
public ProgressMonitorView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
//private static ProgressMonitorView instance;
|
||||
|
||||
//public static ProgressMonitorView Instance
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// instance ??= new ProgressMonitorView();
|
||||
// return instance;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Controls
|
||||
{
|
||||
partial class ProgressMonitorViewModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
public partial int MaxValue { get; set; } = 100;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial int CurrentValue { get; set; } = 0;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string CurrentContext { get; set; } = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Title { get; set; } = "处理任务";
|
||||
|
||||
public void NotifyUI()
|
||||
{
|
||||
var classType = this.GetType();
|
||||
if (classType != null)
|
||||
{
|
||||
var currentProperties = classType.GetProperties();
|
||||
foreach (var currentProperty in currentProperties)
|
||||
OnPropertyChanged(currentProperty.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user