修改路径文件导入重复显示的问题
This commit is contained in:
parent
3012e4752f
commit
9c83af59ca
Binary file not shown.
@ -184,6 +184,12 @@
|
||||
<Compile Include="src\UI\WPF\Views\LayerManagementView.xaml.cs">
|
||||
<DependentUpon>LayerManagementView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="src\UI\WPF\Views\HelpDialog.xaml.cs">
|
||||
<DependentUpon>HelpDialog.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="src\UI\WPF\Views\AboutDialog.xaml.cs">
|
||||
<DependentUpon>AboutDialog.xaml</DependentUpon>
|
||||
</Compile>
|
||||
|
||||
<!-- UI - WPF ViewModels -->
|
||||
<Compile Include="src\UI\WPF\ViewModels\ViewModelBase.cs" />
|
||||
@ -258,6 +264,20 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="src\UI\WPF\Views\HelpDialog.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="src\UI\WPF\Views\AboutDialog.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<!-- Shared Resource Dictionary -->
|
||||
<Page Include="src\UI\WPF\Resources\NavisworksStyles.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WinFX\3.0\Microsoft.WinFX.targets" Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\WinFX\3.0\Microsoft.WinFX.targets')" />
|
||||
|
||||
@ -1,2 +1,31 @@
|
||||
<!-- Core Animation System -->
|
||||
<Compile Include="src\Core\Animation\PathAnimationManager.cs" />
|
||||
<Compile Include="src\Core\Animation\PathAnimationManager.cs" /> <Page Include="src\UI\WPF\Views\AboutDialog.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<!-- Shared Resource Dictionary -->
|
||||
<Page Include="src\UI\WPF\Resources\NavisworksStyles.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup> <Page Include="src\UI\WPF\Views\AboutDialog.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<!-- Shared Resource Dictionary -->
|
||||
<Page Include="src\UI\WPF\Resources\NavisworksStyles.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup> <Page Include="src\UI\WPF\Views\AboutDialog.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<!-- Shared Resource Dictionary -->
|
||||
<Page Include="src\UI\WPF\Resources\NavisworksStyles.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WinFX\3.0\Microsoft.WinFX.targets" Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\WinFX\3.0\Microsoft.WinFX.targets')" />
|
||||
@ -1235,7 +1235,303 @@ private void ShowPositionCorrectionDialog(Point3D originalPos, Point3D corrected
|
||||
- 精度要求高的导航系统
|
||||
- 自动化路径生成工具
|
||||
|
||||
## 13. 线程安全实践经验总结
|
||||
## 13. WPF数据绑定最佳实践:避免自定义集合陷阱
|
||||
|
||||
### 问题描述
|
||||
|
||||
在NavisworksTransport项目中发现了一个经典的WPF数据绑定问题:自定义的 `ThreadSafeObservableCollection` 与WPF标准数据绑定机制不兼容,导致UI显示重复数据。这个问题揭示了"过度工程"的风险以及回归标准实践的重要性。
|
||||
|
||||
### 问题根本原因分析
|
||||
|
||||
#### 13.1 设计理念冲突
|
||||
|
||||
```csharp
|
||||
// ❌ 问题:自定义线程安全集合与WPF冲突
|
||||
public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
|
||||
{
|
||||
// 内部实现复杂的UI线程marshaling
|
||||
private void OnCollectionChanged()
|
||||
{
|
||||
// 自定义的UI线程处理机制
|
||||
_uiStateManager.QueueUIUpdate(() =>
|
||||
{
|
||||
base.OnCollectionChanged(...);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 解决方案:使用WPF标准集合
|
||||
public ObservableCollection<PathRouteViewModel> PathRoutes { get; set; }
|
||||
= new ObservableCollection<PathRouteViewModel>();
|
||||
```
|
||||
|
||||
**核心冲突**:
|
||||
- `ThreadSafeObservableCollection`试图提供线程安全,通过内部机制自动将变更marshaling到UI线程
|
||||
- WPF数据绑定期望使用标准的`ObservableCollection`,由框架本身处理UI线程marshaling
|
||||
- 双重UI线程处理机制导致重复通知和不可预测的行为
|
||||
|
||||
#### 13.2 异步处理复杂性
|
||||
|
||||
```csharp
|
||||
// ❌ 导致问题的异步初始化机制
|
||||
public PathRouteViewModel()
|
||||
{
|
||||
InitializeDefaults();
|
||||
_ = InitializeAsync(); // "火后不理"的异步调用
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||
{
|
||||
// 异步UI更新可能与同步数据创建产生时序问题
|
||||
Points.CollectionChanged += OnPointsCollectionChanged;
|
||||
_isInitialized = true;
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
**时序问题分析**:
|
||||
1. 同步的数据创建(RefreshPathRoutes)
|
||||
2. 异步的UI初始化(InitializeAsync)
|
||||
3. UI更新队列积压(保底定时器强制处理)
|
||||
4. 重复的UI更新执行
|
||||
|
||||
#### 13.3 事件处理重叠
|
||||
|
||||
发现有三个机制同时处理相同的数据变更:
|
||||
```csharp
|
||||
// 机制1:手动刷新
|
||||
RefreshPathRoutes() // 从Core数据创建UI路径点
|
||||
|
||||
// 机制2:事件响应
|
||||
OnPathPointsListUpdated() // 响应路径点更新事件
|
||||
|
||||
// 机制3:路径生成事件
|
||||
OnRouteGenerated() // 处理自动路径生成
|
||||
|
||||
// 结果:同样的路径点被多次添加到UI
|
||||
```
|
||||
|
||||
### 完整解决方案
|
||||
|
||||
#### 13.4 回归WPF标准实践
|
||||
|
||||
```csharp
|
||||
// ✅ 正确做法:使用标准ObservableCollection
|
||||
public class PathEditingViewModel : ViewModelBase
|
||||
{
|
||||
// 路径集合使用标准集合
|
||||
public ObservableCollection<PathRouteViewModel> PathRoutes { get; private set; }
|
||||
= new ObservableCollection<PathRouteViewModel>();
|
||||
}
|
||||
|
||||
public class PathRouteViewModel : ViewModelBase
|
||||
{
|
||||
// 路径点集合也使用标准集合
|
||||
public ObservableCollection<PathPointViewModel> Points { get; private set; }
|
||||
= new ObservableCollection<PathPointViewModel>();
|
||||
|
||||
// 简化初始化:同步完成,无异步复杂性
|
||||
public PathRouteViewModel()
|
||||
{
|
||||
InitializeDefaults();
|
||||
CompleteInitialization();
|
||||
}
|
||||
|
||||
private void CompleteInitialization()
|
||||
{
|
||||
// 直接订阅事件,无需异步
|
||||
Points.CollectionChanged += OnPointsCollectionChanged;
|
||||
_isInitialized = true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 13.5 职责分离和重复检查
|
||||
|
||||
```csharp
|
||||
// ✅ 事件处理器包含重复检查逻辑
|
||||
private async void OnPathPointsListUpdated(object sender, PathPointsListUpdatedEventArgs e)
|
||||
{
|
||||
if (e?.Route == null) return;
|
||||
|
||||
await SafeExecuteAsync(() =>
|
||||
{
|
||||
var pathViewModel = PathRoutes.FirstOrDefault(p => p.Name == e.Route.Name);
|
||||
if (pathViewModel != null)
|
||||
{
|
||||
// 关键:检查是否需要更新,避免重复处理
|
||||
if (pathViewModel.Points.Count == e.Route.Points.Count)
|
||||
{
|
||||
LogManager.Info($"路径点数量已正确({pathViewModel.Points.Count}),跳过重复更新");
|
||||
return;
|
||||
}
|
||||
|
||||
// 执行实际更新
|
||||
pathViewModel.Points.Clear();
|
||||
foreach (var point in e.Route.Points)
|
||||
{
|
||||
// 添加路径点...
|
||||
}
|
||||
}
|
||||
}, "处理路径点列表更新事件");
|
||||
}
|
||||
```
|
||||
|
||||
### 关键经验教训
|
||||
|
||||
#### 13.6 过度工程的陷阱
|
||||
|
||||
**问题**:试图通过复杂的自定义机制"改进"框架的标准行为
|
||||
**结果**:引入了与框架机制的冲突,造成更多问题
|
||||
**教训**:WPF的`ObservableCollection`已经是充分测试的成熟解决方案
|
||||
|
||||
```csharp
|
||||
// ❌ 过度设计:复杂的自定义线程安全集合
|
||||
public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
|
||||
{
|
||||
private readonly UIStateManager _uiStateManager;
|
||||
private readonly object _lockObject = new object();
|
||||
|
||||
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
// 复杂的线程安全逻辑
|
||||
if (_uiStateManager != null)
|
||||
{
|
||||
_uiStateManager.QueueUIUpdate(() => base.OnCollectionChanged(e));
|
||||
}
|
||||
// 与WPF绑定机制产生冲突
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 简单有效:使用标准解决方案
|
||||
public ObservableCollection<T> Items { get; private set; } = new ObservableCollection<T>();
|
||||
```
|
||||
|
||||
#### 13.7 线程安全的正确处理方式
|
||||
|
||||
在WPF中,正确的线程安全做法是:
|
||||
- **数据操作**在适当的线程中执行
|
||||
- **UI更新**统一通过`Dispatcher.Invoke`或`UIStateManager`在UI线程执行
|
||||
- **不要在集合层面**实现线程安全,而是在操作层面控制
|
||||
|
||||
```csharp
|
||||
// ✅ 正确的线程安全模式
|
||||
public async Task AddPathAsync(PathRouteViewModel path)
|
||||
{
|
||||
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||
{
|
||||
PathRoutes.Add(path); // 在UI线程上操作标准集合
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### 13.8 调试复杂问题的方法论
|
||||
|
||||
从这个案例中学到的调试方法:
|
||||
1. **详细日志追踪**:记录事件时序和调用栈
|
||||
2. **识别异步副作用**:关注"火后不理"的异步调用
|
||||
3. **分析处理机制重叠**:多个组件处理相同数据的情况
|
||||
4. **回归简单方案**:当复杂方案出问题时,考虑标准做法
|
||||
|
||||
### 设计原则总结
|
||||
|
||||
#### 13.9 集合使用原则
|
||||
|
||||
```csharp
|
||||
// ✅ WPF UI绑定:使用标准ObservableCollection
|
||||
public ObservableCollection<ItemViewModel> Items { get; private set; }
|
||||
= new ObservableCollection<ItemViewModel>();
|
||||
|
||||
// ✅ 后台数据处理:可以使用线程安全集合
|
||||
private readonly ConcurrentBag<ProcessingItem> _processingQueue
|
||||
= new ConcurrentBag<ProcessingItem>();
|
||||
|
||||
// ✅ UI更新时:统一在UI线程操作
|
||||
public async Task UpdateUI(List<ItemData> newData)
|
||||
{
|
||||
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||
{
|
||||
Items.Clear();
|
||||
foreach (var item in newData)
|
||||
{
|
||||
Items.Add(new ItemViewModel(item));
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### 13.10 ViewModel设计原则
|
||||
|
||||
```csharp
|
||||
// ✅ 保持ViewModel简单和同步
|
||||
public class SimpleViewModel : ViewModelBase
|
||||
{
|
||||
public SimpleViewModel()
|
||||
{
|
||||
// 同步初始化,避免复杂的异步逻辑
|
||||
InitializeProperties();
|
||||
SubscribeToEvents();
|
||||
}
|
||||
|
||||
// ✅ 使用标准属性更改通知
|
||||
private string _status;
|
||||
public string Status
|
||||
{
|
||||
get => _status;
|
||||
set => SetProperty(ref _status, value);
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ 避免复杂的异步初始化
|
||||
public class ComplexViewModel : ViewModelBase
|
||||
{
|
||||
public ComplexViewModel()
|
||||
{
|
||||
_ = InitializeAsync(); // 导致时序问题
|
||||
}
|
||||
|
||||
private async Task InitializeAsync()
|
||||
{
|
||||
// 复杂的异步初始化逻辑
|
||||
// 可能与UI绑定产生冲突
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 适用场景和建议
|
||||
|
||||
#### 13.11 何时使用标准集合
|
||||
|
||||
✅ **使用ObservableCollection的场景**:
|
||||
- WPF数据绑定
|
||||
- UI列表显示
|
||||
- 用户交互集合
|
||||
- ViewModel中的集合属性
|
||||
|
||||
✅ **使用线程安全集合的场景**:
|
||||
- 后台数据处理
|
||||
- 多线程生产者-消费者模式
|
||||
- 缓存和队列
|
||||
- 非UI相关的数据结构
|
||||
|
||||
#### 13.12 实施检查清单
|
||||
|
||||
在代码审查中重点检查:
|
||||
- [ ] ViewModel中的集合是否使用标准`ObservableCollection`?
|
||||
- [ ] 是否避免了"过度设计"的自定义集合?
|
||||
- [ ] UI更新是否统一在UI线程执行?
|
||||
- [ ] 是否存在多个机制处理相同数据的情况?
|
||||
- [ ] 异步初始化是否真的必要?
|
||||
|
||||
### 结论
|
||||
|
||||
这个UI重复问题的根本原因是**试图通过自定义的`ThreadSafeObservableCollection`来"改进"WPF的标准数据绑定,但这种改进引入了与框架机制的冲突,导致重复的UI更新和不可预测的行为**。
|
||||
|
||||
解决方案是**回归WPF的最佳实践,使用标准集合和框架提供的机制**。这个案例很好地说明了在软件开发中,简单、标准的解决方案往往比复杂的自定义方案更可靠。
|
||||
|
||||
## 14. 线程安全实践经验总结
|
||||
|
||||
### 问题描述
|
||||
|
||||
|
||||
323
doc/working/ThreadSafeObservableCollection_Migration_Plan.md
Normal file
323
doc/working/ThreadSafeObservableCollection_Migration_Plan.md
Normal file
@ -0,0 +1,323 @@
|
||||
# ThreadSafeObservableCollection 全面迁移计划
|
||||
|
||||
## 问题背景
|
||||
|
||||
在解决UI重复显示问题的过程中,我们发现了 `ThreadSafeObservableCollection` 与WPF标准数据绑定机制不兼容的根本问题。虽然已经在关键文件(`PathEditingViewModel` 和 `PathRouteViewModel`)中成功修复,但项目中仍有大量使用 `ThreadSafeObservableCollection` 的地方需要评估和迁移。
|
||||
|
||||
## 使用现状分析
|
||||
|
||||
通过代码搜索发现,项目中 `ThreadSafeObservableCollection` 的使用分布如下:
|
||||
|
||||
### 使用位置统计
|
||||
- **ViewModels**: 8个文件使用了约15处
|
||||
- `LogisticsControlViewModel.cs` (4处)
|
||||
- `LayerManagementViewModel.cs` (5处)
|
||||
- `ModelSettingsViewModel.cs` (3处)
|
||||
- `AnimationControlViewModel.cs` (1处)
|
||||
- `SystemManagementViewModel.cs` (1处)
|
||||
- `LogisticsControlViewModelcopy.cs` (5处)
|
||||
- ✅ `PathEditingViewModel.cs` (已迁移)
|
||||
- ✅ `PathRouteViewModel.cs` (已迁移)
|
||||
|
||||
- **核心基础设施**:
|
||||
- `src/UI/WPF/Collections/ThreadSafeObservableCollection.cs` - 核心实现
|
||||
- `src/Core/UIUpdate/Updates/CollectionUpdateOperation.cs` - UIUpdate系统支持
|
||||
- `src/UI/WPF/Services/DataBindingBestPractices.cs` - 最佳实践指导
|
||||
|
||||
- **测试文件**:
|
||||
- `UnitTests/Collections/ThreadSafeObservableCollectionBasicTests.cs`
|
||||
|
||||
## 核心问题分析
|
||||
|
||||
### 1. WPF数据绑定冲突
|
||||
`ThreadSafeObservableCollection` 试图提供线程安全,通过内部机制自动将变更marshaling到UI线程,但与WPF数据绑定期望的标准机制产生冲突:
|
||||
|
||||
```csharp
|
||||
// ❌ 问题:双重UI线程处理机制
|
||||
ThreadSafeObservableCollection 内部处理 + WPF数据绑定机制 = 重复UI更新
|
||||
```
|
||||
|
||||
### 2. 过度工程陷阱
|
||||
自定义的线程安全集合引入了与框架机制的冲突,造成比解决的问题更多的问题。
|
||||
|
||||
## 迁移策略
|
||||
|
||||
### Phase 1: 分类评估 (不破坏现有功能)
|
||||
|
||||
#### 1.1 需要迁移的场景 - WPF UI绑定
|
||||
**原则**: 用于WPF数据绑定的集合应使用标准 `ObservableCollection`
|
||||
|
||||
**需要迁移的文件**:
|
||||
- ✅ `PathEditingViewModel.cs` (已完成)
|
||||
- ✅ `PathRouteViewModel.cs` (已完成)
|
||||
- `LogisticsControlViewModel.cs`
|
||||
- `LayerManagementViewModel.cs`
|
||||
- `ModelSettingsViewModel.cs`
|
||||
- `AnimationControlViewModel.cs`
|
||||
- `SystemManagementViewModel.cs`
|
||||
|
||||
#### 1.2 建议保留的场景 - 后台数据处理
|
||||
**原则**: 非UI绑定的数据集合可以继续使用线程安全集合
|
||||
|
||||
**保留使用的场景**:
|
||||
- 多线程后台处理的临时数据
|
||||
- 缓存和队列等数据结构
|
||||
- 不直接绑定到UI的数据管理
|
||||
|
||||
### Phase 2: 渐进式迁移 (确保稳定性)
|
||||
|
||||
#### 迁移步骤模板
|
||||
|
||||
对于每个需要迁移的ViewModel:
|
||||
|
||||
1. **准备工作**
|
||||
```bash
|
||||
# 备份当前文件
|
||||
copy OriginalViewModel.cs OriginalViewModel.cs.backup
|
||||
```
|
||||
|
||||
2. **代码修改**
|
||||
```csharp
|
||||
// 替换集合声明
|
||||
// ❌ 修改前
|
||||
public ThreadSafeObservableCollection<ItemType> Items { get; private set; }
|
||||
= new ThreadSafeObservableCollection<ItemType>();
|
||||
|
||||
// ✅ 修改后
|
||||
public ObservableCollection<ItemType> Items { get; private set; }
|
||||
= new ObservableCollection<ItemType>();
|
||||
```
|
||||
|
||||
3. **简化初始化**
|
||||
```csharp
|
||||
// ❌ 复杂的异步初始化
|
||||
public ViewModel()
|
||||
{
|
||||
InitializeDefaults();
|
||||
_ = InitializeAsync(); // "火后不理"的异步调用
|
||||
}
|
||||
|
||||
// ✅ 简单的同步初始化
|
||||
public ViewModel()
|
||||
{
|
||||
InitializeDefaults();
|
||||
CompleteInitialization();
|
||||
}
|
||||
```
|
||||
|
||||
4. **添加重复检查**
|
||||
```csharp
|
||||
// ✅ 事件处理器包含重复检查逻辑
|
||||
private async void OnDataUpdated(object sender, DataUpdatedEventArgs e)
|
||||
{
|
||||
if (e?.Data == null) return;
|
||||
|
||||
await SafeExecuteAsync(() =>
|
||||
{
|
||||
// 关键:检查是否需要更新,避免重复处理
|
||||
if (Items.Count == e.Data.Count)
|
||||
{
|
||||
LogManager.Info($"数据数量已正确({Items.Count}),跳过重复更新");
|
||||
return;
|
||||
}
|
||||
|
||||
// 执行实际更新
|
||||
Items.Clear();
|
||||
foreach (var item in e.Data)
|
||||
{
|
||||
Items.Add(item);
|
||||
}
|
||||
}, "处理数据更新事件");
|
||||
}
|
||||
```
|
||||
|
||||
5. **测试验证**
|
||||
- 编译测试:确保无编译错误
|
||||
- 功能测试:验证UI显示正常,无重复数据
|
||||
- 性能测试:确认UI响应性能
|
||||
|
||||
#### 迁移优先级
|
||||
|
||||
1. **高优先级** - 直接用于WPF数据绑定,有UI重复显示风险
|
||||
- `LogisticsControlViewModel.cs`
|
||||
- `LayerManagementViewModel.cs`
|
||||
- `ModelSettingsViewModel.cs`
|
||||
|
||||
2. **中优先级** - 间接影响UI显示
|
||||
- `AnimationControlViewModel.cs`
|
||||
- `SystemManagementViewModel.cs`
|
||||
|
||||
3. **低优先级** - 纯后台数据处理,无直接UI影响
|
||||
- 保留现有实现或根据具体需求决定
|
||||
|
||||
### Phase 3: 架构优化 (长期改进)
|
||||
|
||||
#### 3.1 使用原则制定
|
||||
|
||||
建立清晰的集合选择原则:
|
||||
|
||||
```csharp
|
||||
// ✅ WPF UI绑定场景
|
||||
public ObservableCollection<T> UIBoundItems { get; private set; }
|
||||
= new ObservableCollection<T>();
|
||||
|
||||
// ✅ 后台数据处理场景
|
||||
private readonly ConcurrentBag<T> _processingQueue
|
||||
= new ConcurrentBag<T>();
|
||||
|
||||
// ✅ UI更新统一处理
|
||||
public async Task UpdateUI(List<T> newData)
|
||||
{
|
||||
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||
{
|
||||
UIBoundItems.Clear();
|
||||
foreach (var item in newData)
|
||||
{
|
||||
UIBoundItems.Add(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2 重构建议
|
||||
|
||||
1. **保持向后兼容**
|
||||
- 继续维护 `ThreadSafeObservableCollection` 类
|
||||
- 保留 `CollectionUpdateOperation` 的支持
|
||||
- 更新文档说明使用场景
|
||||
|
||||
2. **架构清晰化**
|
||||
- WPF UI绑定 → 标准 `ObservableCollection`
|
||||
- 后台数据处理 → `ThreadSafeObservableCollection` 或 `ConcurrentCollection`
|
||||
- 线程安全更新 → 统一通过 `UIStateManager` 处理
|
||||
|
||||
## 详细迁移计划
|
||||
|
||||
### 第一批迁移: LogisticsControlViewModel
|
||||
```csharp
|
||||
// 需要迁移的属性:
|
||||
- LogisticsModels (ThreadSafeObservableCollection<LogisticsModel>)
|
||||
- AvailableCategories (ThreadSafeObservableCollection<string>)
|
||||
- AvailableFrameRates (ThreadSafeObservableCollection<int>)
|
||||
```
|
||||
|
||||
**验证项目**:
|
||||
- [ ] 物流模型显示正常
|
||||
- [ ] 分类选择功能正常
|
||||
- [ ] 帧率设置功能正常
|
||||
- [ ] 无UI重复显示问题
|
||||
|
||||
### 第二批迁移: LayerManagementViewModel
|
||||
```csharp
|
||||
// 需要迁移的属性:
|
||||
- AvailableAttributes (ThreadSafeObservableCollection<string>)
|
||||
- DepthOptions (ThreadSafeObservableCollection<string>)
|
||||
- SplitStrategies (ThreadSafeObservableCollection<string>)
|
||||
- SplitPreviewResults (ThreadSafeObservableCollection<SplitPreviewItem>)
|
||||
```
|
||||
|
||||
**验证项目**:
|
||||
- [ ] 图层管理界面显示正常
|
||||
- [ ] 属性选择功能正常
|
||||
- [ ] 模型分割预览功能正常
|
||||
- [ ] 分割策略选择正常
|
||||
|
||||
### 第三批迁移: ModelSettingsViewModel
|
||||
```csharp
|
||||
// 需要迁移的属性:
|
||||
- AvailableCategories (ThreadSafeObservableCollection<string>)
|
||||
- PriorityLevels (ThreadSafeObservableCollection<int>)
|
||||
- LogisticsModels (ThreadSafeObservableCollection<LogisticsModel>)
|
||||
```
|
||||
|
||||
**验证项目**:
|
||||
- [ ] 模型设置界面显示正常
|
||||
- [ ] 分类设置功能正常
|
||||
- [ ] 优先级设置功能正常
|
||||
|
||||
### 第四批迁移: 其他ViewModels
|
||||
- `AnimationControlViewModel.cs` - AvailableFrameRates
|
||||
- `SystemManagementViewModel.cs` - LogLevels
|
||||
|
||||
## 风险评估与缓解措施
|
||||
|
||||
### 风险1: UI性能问题
|
||||
**风险等级**: 中等
|
||||
**缓解措施**:
|
||||
- 分阶段迁移,每次迁移后进行性能测试
|
||||
- 监控UI响应时间,如有问题及时回滚
|
||||
|
||||
### 风险2: 多线程并发问题
|
||||
**风险等级**: 中等
|
||||
**缓解措施**:
|
||||
- 保留UIStateManager机制,确保UI更新线程安全
|
||||
- 对非UI绑定的数据处理场景保留ThreadSafeObservableCollection
|
||||
|
||||
### 风险3: 现有功能破坏
|
||||
**风险等级**: 低
|
||||
**缓解措施**:
|
||||
- 每个ViewModel迁移完成后进行完整功能测试
|
||||
- 保留备份文件,支持快速回滚
|
||||
- 渐进式迁移,一次只处理一个ViewModel
|
||||
|
||||
### 风险4: 团队学习成本
|
||||
**风险等级**: 低
|
||||
**缓解措施**:
|
||||
- 提供清晰的迁移指南和代码示例
|
||||
- 在设计文档中明确新的使用原则
|
||||
|
||||
## 预期收益
|
||||
|
||||
### 短期收益
|
||||
1. **消除UI重复显示问题** - 避免双重UI更新机制冲突
|
||||
2. **提高代码可靠性** - 使用经过充分测试的标准WPF机制
|
||||
3. **简化调试过程** - 减少自定义机制带来的复杂性
|
||||
|
||||
### 长期收益
|
||||
1. **遵循WPF最佳实践** - 与框架设计理念保持一致
|
||||
2. **提高代码可维护性** - 减少自定义实现的维护负担
|
||||
3. **改善团队开发效率** - 新团队成员更容易理解标准WPF模式
|
||||
|
||||
## 实施时间表
|
||||
|
||||
**建议时间安排**:
|
||||
- Phase 1 (评估阶段): 已完成
|
||||
- Phase 2 (渐进式迁移): 2-4周
|
||||
- 第一批迁移: 1周
|
||||
- 第二批迁移: 1周
|
||||
- 第三、四批迁移: 1-2周
|
||||
- Phase 3 (架构优化): 1周
|
||||
- 文档更新和代码清理
|
||||
|
||||
**里程碑检查点**:
|
||||
- 每批迁移完成后进行功能验证
|
||||
- 所有迁移完成后进行全面集成测试
|
||||
- 最终进行性能和稳定性测试
|
||||
|
||||
## 结论
|
||||
|
||||
这个迁移计划基于实际发现的UI重复显示问题,采用渐进式、风险可控的方式,在保证现有功能正常的前提下,逐步解决架构问题,最终建立更健壮、更符合WPF最佳实践的集合管理机制。
|
||||
|
||||
通过这次迁移,我们不仅解决了具体的技术问题,更重要的是建立了"简单、标准的解决方案往往比复杂的自定义方案更可靠"的架构理念。
|
||||
|
||||
---
|
||||
|
||||
## 附录
|
||||
|
||||
### A. 相关文档
|
||||
- [设计原则文档 - WPF数据绑定最佳实践](../guide/design_principles.md#13-wpf数据绑定最佳实践避免自定义集合陷阱)
|
||||
- [ThreadSafeObservableCollection实现总结](../memories/threadsafe_observable_collection_implementation.md)
|
||||
|
||||
### B. 参考代码示例
|
||||
参考已成功迁移的文件:
|
||||
- `src/UI/WPF/ViewModels/PathEditingViewModel.cs`
|
||||
- `src/UI/WPF/Models/PathRouteViewModel.cs`
|
||||
|
||||
### C. 迁移检查清单
|
||||
- [ ] 集合声明已更改为ObservableCollection
|
||||
- [ ] 构造函数已简化为同步初始化
|
||||
- [ ] 事件处理器包含重复检查逻辑
|
||||
- [ ] 编译无错误无警告
|
||||
- [ ] UI显示功能正常
|
||||
- [ ] 无重复数据显示
|
||||
- [ ] 性能无明显退化
|
||||
@ -507,34 +507,6 @@ namespace NavisworksTransport.Commands
|
||||
UpdateProgress(85, "正在完成导入操作...");
|
||||
ThrowIfCancellationRequested(cancellationToken);
|
||||
|
||||
// 第六阶段:后处理(90%)
|
||||
UpdateProgress(90, "正在完成导入后处理...");
|
||||
|
||||
try
|
||||
{
|
||||
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||
{
|
||||
// 自动选择第一个导入的路径为当前路径
|
||||
if (_parameters.AutoSelectFirstRoute && result.ImportedCount > 0)
|
||||
{
|
||||
var firstImportedRoute = _pathPlanningManager.Routes
|
||||
.Where(r => result.ImportedPaths.Any(ip => ip.StartsWith(r.Name)))
|
||||
.FirstOrDefault();
|
||||
|
||||
if (firstImportedRoute != null)
|
||||
{
|
||||
_pathPlanningManager.SetCurrentRoute(firstImportedRoute);
|
||||
LogInfo($"已自动选择路径为当前路径: {firstImportedRoute.Name}");
|
||||
}
|
||||
}
|
||||
LogInfo("UI状态已刷新");
|
||||
});
|
||||
}
|
||||
catch (Exception refreshEx)
|
||||
{
|
||||
LogWarning($"刷新UI状态失败: {refreshEx.Message}");
|
||||
}
|
||||
|
||||
// 完成(100%)
|
||||
UpdateProgress(100, "路径导入完成");
|
||||
|
||||
|
||||
@ -2918,19 +2918,8 @@ namespace NavisworksTransport
|
||||
|
||||
refreshPathList(); // 初始加载
|
||||
|
||||
// 监听路径生成事件,自动刷新路径列表
|
||||
var activePathManager = PathPlanningManager.GetActivePathManager();
|
||||
if (activePathManager != null)
|
||||
{
|
||||
activePathManager.RouteGenerated += (sender, route) =>
|
||||
{
|
||||
GlobalExceptionHandler.SafeExecute(() =>
|
||||
{
|
||||
LogManager.Info($"检测到新路径生成:{route?.Name},自动刷新动画控制面板路径列表");
|
||||
refreshPathList();
|
||||
}, "路径生成事件处理");
|
||||
};
|
||||
}
|
||||
// 注意:路径生成事件的UI更新已由PathEditingViewModel处理,避免重复订阅
|
||||
// 如果需要特殊的动画面板刷新逻辑,应该通过其他方式实现
|
||||
|
||||
// 生成动画事件处理
|
||||
createAnimationButton.Click += (sender, e) =>
|
||||
|
||||
@ -988,14 +988,15 @@ namespace NavisworksTransport
|
||||
_routes.Add(route);
|
||||
RaiseStatusChanged($"已添加路径: {route.Name}", PathPlanningStatusType.Success);
|
||||
|
||||
// 如果当前没有活动路径,设置此路径为活动路径
|
||||
if (_currentRoute == null || _currentRoute.Points.Count == 0)
|
||||
{
|
||||
CurrentRoute = route;
|
||||
}
|
||||
// AddRoute只负责添加路径到数据集合,不自动设置当前路径
|
||||
// 路径选择应该通过专门的选择逻辑处理,而不是添加操作的副作用
|
||||
// if (_currentRoute == null || _currentRoute.Points.Count == 0)
|
||||
// {
|
||||
// CurrentRoute = route;
|
||||
// }
|
||||
|
||||
// 触发路径生成事件
|
||||
RaiseRouteGenerated(route, RouteGenerationMethod.Manual);
|
||||
// 注释掉多余的路径生成事件调用,Manual类型路径通过UI层的RefreshPathRoutes()统一刷新
|
||||
// RaiseRouteGenerated(route, RouteGenerationMethod.Manual);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1,3 +1,15 @@
|
||||
<!--
|
||||
NavisworksTransport 主控制面板 - 采用与其他视图一致的Navisworks 2026风格
|
||||
|
||||
功能说明:
|
||||
1. 分层管理:模型分层控制和可见性管理
|
||||
2. 类别设置:物流类别设置和属性管理
|
||||
3. 路径编辑:3D路径规划和编辑功能
|
||||
4. 检测动画:路径动画生成和碰撞检测
|
||||
5. 系统管理:日志管理、插件设置和性能监控
|
||||
|
||||
设计原则:与Navisworks 2026风格一致,480像素宽度,现代化UI布局
|
||||
-->
|
||||
<UserControl x:Class="NavisworksTransport.UI.WPF.LogisticsControlPanel"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
@ -6,6 +18,16 @@
|
||||
xmlns:views="clr-namespace:NavisworksTransport.UI.WPF.Views"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="700" d:DesignWidth="480">
|
||||
|
||||
<UserControl.Resources>
|
||||
<!-- 引用共享的Navisworks 2026样式资源 -->
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/NavisworksTransportPlugin;component/src/UI/WPF/Resources/NavisworksStyles.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
@ -13,32 +35,60 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<TabControl Grid.Row="0" Name="MainTabControl" Margin="5">
|
||||
<TabItem Header="分层管理" Name="LayerManagementTab">
|
||||
<ContentControl x:Name="LayerManagementContent"/>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="类别设置" Name="ModelSettingsTab">
|
||||
<ContentControl x:Name="ModelSettingsContent"/>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="路径编辑" Name="PathEditingTab">
|
||||
<views:PathEditingView x:Name="PathEditingView"/>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="检测动画" Name="AnimationControlTab">
|
||||
<views:AnimationControlView x:Name="AnimationControlView"/>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="系统管理" Name="SystemManagementTab">
|
||||
<views:SystemManagementView x:Name="SystemManagementView"/>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
<TabControl Grid.Row="0"
|
||||
Name="MainTabControl"
|
||||
Style="{StaticResource NavisworksTabControlStyle}"
|
||||
Margin="10,10,10,5">
|
||||
<TabItem Header="分层管理" Name="LayerManagementTab" Style="{StaticResource NavisworksTabItemStyle}">
|
||||
<Border Background="White" CornerRadius="0">
|
||||
<ContentControl x:Name="LayerManagementContent" Margin="0"/>
|
||||
</Border>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="类别设置" Name="ModelSettingsTab" Style="{StaticResource NavisworksTabItemStyle}">
|
||||
<Border Background="White" CornerRadius="0">
|
||||
<ContentControl x:Name="ModelSettingsContent" Margin="0"/>
|
||||
</Border>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="路径编辑" Name="PathEditingTab" Style="{StaticResource NavisworksTabItemStyle}">
|
||||
<Border Background="White" CornerRadius="0">
|
||||
<views:PathEditingView x:Name="PathEditingView" Margin="0"/>
|
||||
</Border>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="检测动画" Name="AnimationControlTab" Style="{StaticResource NavisworksTabItemStyle}">
|
||||
<Border Background="White" CornerRadius="0">
|
||||
<views:AnimationControlView x:Name="AnimationControlView" Margin="0"/>
|
||||
</Border>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="系统管理" Name="SystemManagementTab" Style="{StaticResource NavisworksTabItemStyle}">
|
||||
<Border Background="White" CornerRadius="0">
|
||||
<views:SystemManagementView x:Name="SystemManagementView" Margin="0"/>
|
||||
</Border>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="10">
|
||||
<Button Content="帮助" Click="HelpButton_Click" Margin="0,0,10,0"/>
|
||||
<Button Content="关于" Click="AboutButton_Click" Margin="0,0,10,0"/>
|
||||
</StackPanel>
|
||||
<Border Grid.Row="1"
|
||||
BorderBrush="#FFD4E7FF"
|
||||
BorderThickness="1"
|
||||
CornerRadius="0"
|
||||
Background="#FFF8FBFF"
|
||||
Margin="10,5,10,10"
|
||||
Padding="12,8">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Right">
|
||||
<Button Content="帮助"
|
||||
Click="HelpButton_Click"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
ToolTip="查看插件使用说明和操作指南"/>
|
||||
<Button Content="关于"
|
||||
Click="AboutButton_Click"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
ToolTip="查看插件版本信息和开发者信息"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -253,8 +253,11 @@ namespace NavisworksTransport.UI.WPF
|
||||
{
|
||||
GlobalExceptionHandler.SafeExecute(() =>
|
||||
{
|
||||
MessageBox.Show("物流路径规划插件使用说明:\n\n1. 类别设置:设置对象类别和可见性\n2. 路径编辑:创建和管理3D路径\n3. 动画控制:创建路径动画\n4. 系统管理:插件设置和日志",
|
||||
"帮助", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
var helpDialog = new Views.HelpDialog
|
||||
{
|
||||
Owner = Window.GetWindow(this)
|
||||
};
|
||||
helpDialog.ShowDialog();
|
||||
}, "显示帮助");
|
||||
}
|
||||
|
||||
@ -265,8 +268,11 @@ namespace NavisworksTransport.UI.WPF
|
||||
{
|
||||
GlobalExceptionHandler.SafeExecute(() =>
|
||||
{
|
||||
MessageBox.Show("物流路径规划插件 v1.0\n\n适用于 Navisworks 2026\n\n功能:3D路径规划、动画创建、碰撞检测",
|
||||
"关于插件", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
var aboutDialog = new Views.AboutDialog
|
||||
{
|
||||
Owner = Window.GetWindow(this)
|
||||
};
|
||||
aboutDialog.ShowDialog();
|
||||
}, "显示关于");
|
||||
}
|
||||
|
||||
|
||||
@ -145,7 +145,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
#region 私有字段
|
||||
|
||||
private string _name;
|
||||
private ThreadSafeObservableCollection<PathPointViewModel> _points;
|
||||
private ObservableCollection<PathPointViewModel> _points;
|
||||
private bool _isActive;
|
||||
private string _description;
|
||||
private bool _isOptimal;
|
||||
@ -181,9 +181,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 路径点集合(线程安全)
|
||||
/// 路径点集合
|
||||
/// </summary>
|
||||
public ThreadSafeObservableCollection<PathPointViewModel> Points
|
||||
public ObservableCollection<PathPointViewModel> Points
|
||||
{
|
||||
get => _points;
|
||||
private set => SetProperty(ref _points, value);
|
||||
@ -329,8 +329,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 初始化默认值
|
||||
InitializeDefaults();
|
||||
|
||||
// 异步初始化
|
||||
_ = InitializeAsync();
|
||||
// 直接完成初始化,不需要异步
|
||||
CompleteInitialization();
|
||||
|
||||
LogManager.Debug($"PathRouteViewModel构造函数完成:{_name}");
|
||||
}
|
||||
@ -379,33 +379,43 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
_isValidated = false;
|
||||
_validationStatus = "未验证";
|
||||
|
||||
// 初始化线程安全的点集合
|
||||
Points = new ThreadSafeObservableCollection<PathPointViewModel>();
|
||||
// 初始化点集合
|
||||
Points = new ObservableCollection<PathPointViewModel>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步初始化方法
|
||||
/// 完成初始化
|
||||
/// </summary>
|
||||
private void CompleteInitialization()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 订阅Points集合变更事件
|
||||
if (Points != null)
|
||||
{
|
||||
Points.CollectionChanged += OnPointsCollectionChanged;
|
||||
}
|
||||
|
||||
// 设置初始化完成标志
|
||||
_isInitialized = true;
|
||||
OnPropertyChanged(nameof(IsInitialized));
|
||||
|
||||
LogManager.Debug($"PathRouteViewModel初始化完成:{_name}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"PathRouteViewModel初始化异常: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步初始化方法(保留用于向后兼容)
|
||||
/// </summary>
|
||||
/// <returns>异步任务</returns>
|
||||
[Obsolete("已改为同步初始化,此方法保留用于向后兼容")]
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await SafeExecuteAsync(async () =>
|
||||
{
|
||||
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||
{
|
||||
// 订阅Points集合变更事件
|
||||
if (Points != null)
|
||||
{
|
||||
Points.CollectionChanged += OnPointsCollectionChanged;
|
||||
}
|
||||
|
||||
// 设置初始化完成标志
|
||||
_isInitialized = true;
|
||||
OnPropertyChanged(nameof(IsInitialized));
|
||||
|
||||
LogManager.Debug($"PathRouteViewModel异步初始化完成:{_name}");
|
||||
});
|
||||
}, "异步初始化PathRouteViewModel");
|
||||
await Task.CompletedTask; // 现在初始化已经在构造函数中同步完成
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -485,7 +495,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||
{
|
||||
Points.AddRange(pointList);
|
||||
foreach (var point in pointList)
|
||||
{
|
||||
Points.Add(point);
|
||||
}
|
||||
LogManager.Debug($"批量添加{pointList.Count}个路径点到路径 {_name}");
|
||||
});
|
||||
}, "批量添加路径点");
|
||||
@ -550,7 +563,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
double totalLength = 0.0;
|
||||
var pointsSnapshot = Points.ToSnapshot();
|
||||
var pointsSnapshot = Points.ToList();
|
||||
|
||||
for (int i = 0; i < pointsSnapshot.Count - 1; i++)
|
||||
{
|
||||
@ -612,7 +625,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
|
||||
// 检查重复点
|
||||
var duplicatePoints = Points.ToSnapshot()
|
||||
var duplicatePoints = Points.ToList()
|
||||
.GroupBy(p => new { p.X, p.Y, p.Z })
|
||||
.Where(g => g.Count() > 1)
|
||||
.ToList();
|
||||
|
||||
195
src/UI/WPF/Resources/NavisworksStyles.xaml
Normal file
195
src/UI/WPF/Resources/NavisworksStyles.xaml
Normal file
@ -0,0 +1,195 @@
|
||||
<!--
|
||||
NavisworksTransport 共享样式资源字典 - Navisworks 2026风格
|
||||
功能说明:
|
||||
1. 统一管理所有UI组件的样式定义
|
||||
2. 保持与Navisworks 2026风格一致的设计
|
||||
3. 简化样式维护和修改
|
||||
|
||||
设计原则:蓝色主题配色,现代化布局,统一字体
|
||||
-->
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<!-- Navisworks 2026 主要颜色定义 -->
|
||||
<Color x:Key="NavisworksPrimaryBlue">#FF2B579A</Color>
|
||||
<Color x:Key="NavisworksSecondaryBlue">#FF4472C4</Color>
|
||||
<Color x:Key="NavisworksLightBlue">#FFD4E7FF</Color>
|
||||
<Color x:Key="NavisworksBackgroundBlue">#FFF8FBFF</Color>
|
||||
<Color x:Key="NavisworksButtonBlue">#FFE7F1FF</Color>
|
||||
<Color x:Key="NavisworksTextGray">#FF666666</Color>
|
||||
<Color x:Key="NavisworksDarkGray">#FF333333</Color>
|
||||
|
||||
<!-- Navisworks 2026 画刷定义 -->
|
||||
<SolidColorBrush x:Key="NavisworksPrimaryBrush" Color="{StaticResource NavisworksPrimaryBlue}"/>
|
||||
<SolidColorBrush x:Key="NavisworksSecondaryBrush" Color="{StaticResource NavisworksSecondaryBlue}"/>
|
||||
<SolidColorBrush x:Key="NavisworksLightBrush" Color="{StaticResource NavisworksLightBlue}"/>
|
||||
<SolidColorBrush x:Key="NavisworksBackgroundBrush" Color="{StaticResource NavisworksBackgroundBlue}"/>
|
||||
<SolidColorBrush x:Key="NavisworksButtonBrush" Color="{StaticResource NavisworksButtonBlue}"/>
|
||||
<SolidColorBrush x:Key="NavisworksTextBrush" Color="{StaticResource NavisworksTextGray}"/>
|
||||
<SolidColorBrush x:Key="NavisworksDarkBrush" Color="{StaticResource NavisworksDarkGray}"/>
|
||||
|
||||
<!-- 区域标题样式 -->
|
||||
<Style x:Key="SectionHeaderStyle" TargetType="Label">
|
||||
<Setter Property="FontWeight" Value="Normal"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksPrimaryBrush}"/>
|
||||
<Setter Property="Padding" Value="0,5,0,2"/>
|
||||
</Style>
|
||||
|
||||
<!-- 主要操作按钮样式 -->
|
||||
<Style x:Key="ActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource NavisworksSecondaryBrush}"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource NavisworksPrimaryBrush}"/>
|
||||
<Setter Property="Padding" Value="10,5"/>
|
||||
<Setter Property="Margin" Value="0,0,10,0"/>
|
||||
<Setter Property="FontWeight" Value="Normal"/>
|
||||
<Setter Property="MinWidth" Value="60"/>
|
||||
<Setter Property="Height" Value="28"/>
|
||||
</Style>
|
||||
|
||||
<!-- 次要操作按钮样式 -->
|
||||
<Style x:Key="SecondaryButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource NavisworksButtonBrush}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksPrimaryBrush}"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource NavisworksSecondaryBrush}"/>
|
||||
<Setter Property="Padding" Value="8,4"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
<Setter Property="MinWidth" Value="60"/>
|
||||
<Setter Property="Height" Value="28"/>
|
||||
</Style>
|
||||
|
||||
<!-- 状态文本样式 -->
|
||||
<Style x:Key="StatusTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksTextBrush}"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
</Style>
|
||||
|
||||
<!-- 参数标签样式 -->
|
||||
<Style x:Key="ParameterLabelStyle" TargetType="Label">
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="0,0,5,0"/>
|
||||
</Style>
|
||||
|
||||
<!-- 参数输入框样式 -->
|
||||
<Style x:Key="ParameterInputStyle" TargetType="TextBox">
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="Margin" Value="5,2"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<!-- 单位标签样式 -->
|
||||
<Style x:Key="UnitLabelStyle" TargetType="Label">
|
||||
<Setter Property="Width" Value="30"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="2,0,0,0"/>
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksTextBrush}"/>
|
||||
</Style>
|
||||
|
||||
<!-- 只读文本框样式 -->
|
||||
<Style x:Key="ReadOnlyTextBoxStyle" TargetType="TextBox">
|
||||
<Setter Property="IsReadOnly" Value="True"/>
|
||||
<Setter Property="Background" Value="#FFF5F5F5"/>
|
||||
<Setter Property="BorderBrush" Value="#FFCCCCCC"/>
|
||||
<Setter Property="Padding" Value="5,3"/>
|
||||
<Setter Property="Margin" Value="5,2"/>
|
||||
</Style>
|
||||
|
||||
<!-- TabControl样式定义 -->
|
||||
<Style x:Key="NavisworksTabControlStyle" TargetType="TabControl">
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource NavisworksLightBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
</Style>
|
||||
|
||||
<!-- TabItem样式定义 -->
|
||||
<Style x:Key="NavisworksTabItemStyle" TargetType="TabItem">
|
||||
<Setter Property="Background" Value="{StaticResource NavisworksBackgroundBrush}"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource NavisworksLightBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="1,1,1,0"/>
|
||||
<Setter Property="Margin" Value="0,0,2,0"/>
|
||||
<Setter Property="Padding" Value="12,6"/>
|
||||
<Setter Property="FontWeight" Value="Normal"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksPrimaryBrush}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="TabItem">
|
||||
<Border Name="Border"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="0">
|
||||
<ContentPresenter ContentSource="Header"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter TargetName="Border" Property="Background" Value="White"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksPrimaryBrush}"/>
|
||||
<Setter Property="FontWeight" Value="Normal"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="Border" Property="Background" Value="{StaticResource NavisworksButtonBrush}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- 对话框专用样式 -->
|
||||
<Style x:Key="DialogTitleStyle" TargetType="Label">
|
||||
<Setter Property="FontWeight" Value="Normal"/>
|
||||
<Setter Property="FontSize" Value="18"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksPrimaryBrush}"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="0,10,0,8"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="DialogVersionStyle" TargetType="Label">
|
||||
<Setter Property="FontWeight" Value="Normal"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksSecondaryBrush}"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="0,5,0,5"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="DialogInfoLabelStyle" TargetType="Label">
|
||||
<Setter Property="FontWeight" Value="Normal"/>
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksPrimaryBrush}"/>
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="Padding" Value="0,4"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="DialogInfoTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksDarkBrush}"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
<Setter Property="Margin" Value="10,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="DialogDescriptionStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksTextBrush}"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
<Setter Property="TextAlignment" Value="Center"/>
|
||||
<Setter Property="LineHeight" Value="16"/>
|
||||
<Setter Property="Margin" Value="20,15"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="DialogContentTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksDarkBrush}"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
<Setter Property="LineHeight" Value="16"/>
|
||||
<Setter Property="Margin" Value="10,2,0,4"/>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
@ -5,12 +5,16 @@ using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using Microsoft.Win32;
|
||||
using Autodesk.Navisworks.Api;
|
||||
using NavisworksTransport.Core;
|
||||
using NavisworksTransport.UI.WPF.Collections;
|
||||
using NavisworksTransport.UI.WPF.Models;
|
||||
using NavisworksTransport.UI.WPF.Commands;
|
||||
using NavisworksTransport.Utils;
|
||||
using NavisworksTransport.Commands;
|
||||
using NavisworksTransport.PathPlanning;
|
||||
|
||||
namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
@ -25,9 +29,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
private PathPlanningManager _pathPlanningManager;
|
||||
private readonly UIStateManager _uiStateManager;
|
||||
private readonly PathDataManager _pathDataManager;
|
||||
|
||||
// 路径集合
|
||||
private ThreadSafeObservableCollection<PathRouteViewModel> _pathRoutes;
|
||||
private ObservableCollection<PathRouteViewModel> _pathRoutes;
|
||||
private PathRouteViewModel _selectedPathRoute;
|
||||
private bool _isPathEditMode;
|
||||
|
||||
@ -55,7 +60,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
#region 公共属性
|
||||
|
||||
public ThreadSafeObservableCollection<PathRouteViewModel> PathRoutes
|
||||
public ObservableCollection<PathRouteViewModel> PathRoutes
|
||||
{
|
||||
get => _pathRoutes;
|
||||
set => SetProperty(ref _pathRoutes, value);
|
||||
@ -230,7 +235,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
public bool CanExecuteClearPath => SelectedPathRoute != null && SelectedPathRoute.Points.Count > 0;
|
||||
|
||||
public bool CanExecuteExportPath => SelectedPathRoute != null && SelectedPathRoute.Points.Count > 0;
|
||||
public bool CanExecuteExportPath => _pathPlanningManager?.Routes?.Count > 0;
|
||||
|
||||
public bool CanExecuteSaveAsPath => SelectedPathRoute != null && SelectedPathRoute.Points.Count > 0;
|
||||
|
||||
@ -243,6 +248,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
try
|
||||
{
|
||||
_uiStateManager = UIStateManager.Instance;
|
||||
_pathDataManager = new PathDataManager();
|
||||
// 不在构造函数中创建PathPlanningManager,由外部设置
|
||||
_pathPlanningManager = null;
|
||||
|
||||
@ -254,7 +260,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// PathPlanningManager将在外部设置,这里不需要检查
|
||||
|
||||
// 初始化集合
|
||||
PathRoutes = new ThreadSafeObservableCollection<PathRouteViewModel>();
|
||||
PathRoutes = new ObservableCollection<PathRouteViewModel>();
|
||||
|
||||
// 初始化命令
|
||||
InitializeCommands();
|
||||
@ -788,15 +794,99 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
#endregion
|
||||
|
||||
#region 文件管理命令 - 待实现
|
||||
#region 文件管理命令
|
||||
|
||||
private async Task ExecuteImportPathAsync()
|
||||
{
|
||||
await SafeExecuteAsync(async () =>
|
||||
{
|
||||
// TODO: 实现文件导入逻辑
|
||||
await Task.CompletedTask;
|
||||
AutoPathStatus = "路径导入功能待实现";
|
||||
try
|
||||
{
|
||||
// 打开文件选择对话框
|
||||
var openFileDialog = new OpenFileDialog
|
||||
{
|
||||
Title = "导入路径文件",
|
||||
Filter = "路径文件 (*.xml;*.json)|*.xml;*.json|XML文件 (*.xml)|*.xml|JSON文件 (*.json)|*.json|所有文件 (*.*)|*.*",
|
||||
FilterIndex = 1,
|
||||
CheckFileExists = true,
|
||||
CheckPathExists = true
|
||||
};
|
||||
|
||||
if (openFileDialog.ShowDialog() == true)
|
||||
{
|
||||
var filePath = openFileDialog.FileName;
|
||||
var extension = Path.GetExtension(filePath).ToLower();
|
||||
|
||||
// 确定导入格式
|
||||
var importFormat = extension == ".json" ? ExportFormat.Json : ExportFormat.Xml;
|
||||
|
||||
// 创建导入参数
|
||||
var importParameters = new ImportPathParameters
|
||||
{
|
||||
FilePath = filePath,
|
||||
ImportFormat = importFormat,
|
||||
MergeWithExisting = true,
|
||||
CreateBackup = true,
|
||||
DuplicateHandling = DuplicateNameHandling.Rename,
|
||||
ValidateImportedData = true,
|
||||
AutoSelectFirstRoute = true,
|
||||
Description = $"导入路径文件: {Path.GetFileName(filePath)}"
|
||||
};
|
||||
|
||||
// 创建并执行导入命令
|
||||
var importCommand = new ImportPathCommand(importParameters, _pathPlanningManager);
|
||||
var result = await importCommand.ExecuteAsync();
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
// 更新UI状态
|
||||
RefreshPathRoutes();
|
||||
|
||||
// 如果需要自动选择第一个导入的路径,通过专门的选择逻辑处理
|
||||
if (importParameters.AutoSelectFirstRoute && PathRoutes.Count > 0)
|
||||
{
|
||||
var firstRoute = PathRoutes.FirstOrDefault();
|
||||
if (firstRoute != null)
|
||||
{
|
||||
SelectedPathRoute = firstRoute;
|
||||
LogManager.Info($"导入完成后自动选择路径: {firstRoute.Name}");
|
||||
}
|
||||
}
|
||||
|
||||
var importResult = (result as PathPlanningResult<ImportPathResult>)?.Data;
|
||||
if (importResult != null)
|
||||
{
|
||||
AutoPathStatus = $"✅ 导入成功: {importResult.ImportedCount}/{importResult.TotalInFile} 个路径";
|
||||
if (importResult.FailedCount > 0)
|
||||
{
|
||||
AutoPathStatus += $" (失败 {importResult.FailedCount} 个)";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(importResult.BackupFilePath))
|
||||
{
|
||||
LogManager.Info($"导入前备份已创建: {importResult.BackupFilePath}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AutoPathStatus = $"✅ 路径导入完成: {Path.GetFileName(filePath)}";
|
||||
}
|
||||
|
||||
PathFileStatus = "已导入";
|
||||
}
|
||||
else
|
||||
{
|
||||
AutoPathStatus = $"❌ 导入失败: {result.ErrorMessage}";
|
||||
PathFileStatus = "导入失败";
|
||||
LogManager.Error($"路径导入失败: {result.ErrorMessage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"导入路径异常: {ex.Message}", ex);
|
||||
AutoPathStatus = $"❌ 导入异常: {ex.Message}";
|
||||
PathFileStatus = "导入异常";
|
||||
}
|
||||
}, "导入路径");
|
||||
}
|
||||
|
||||
@ -806,10 +896,76 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
await SafeExecuteAsync(async () =>
|
||||
{
|
||||
// TODO: 实现文件导出逻辑
|
||||
await Task.CompletedTask;
|
||||
AutoPathStatus = $"导出路径: {SelectedPathRoute.Name}";
|
||||
PathFileStatus = "已保存";
|
||||
try
|
||||
{
|
||||
// 打开文件保存对话框
|
||||
var saveFileDialog = new SaveFileDialog
|
||||
{
|
||||
Title = "导出所有路径",
|
||||
Filter = "XML文件 (*.xml)|*.xml|JSON文件 (*.json)|*.json|所有文件 (*.*)|*.*",
|
||||
FilterIndex = 1,
|
||||
FileName = $"路径导出_{DateTime.Now:yyyyMMdd_HHmmss}",
|
||||
DefaultExt = "xml",
|
||||
AddExtension = true
|
||||
};
|
||||
|
||||
if (saveFileDialog.ShowDialog() == true)
|
||||
{
|
||||
var filePath = saveFileDialog.FileName;
|
||||
var extension = Path.GetExtension(filePath).ToLower();
|
||||
|
||||
// 确定导出格式
|
||||
var exportFormat = extension == ".json" ? ExportFormat.Json : ExportFormat.Xml;
|
||||
|
||||
// 创建导出参数 - 导出所有路径
|
||||
var exportParameters = new ExportPathParameters
|
||||
{
|
||||
ExportAll = true,
|
||||
OutputFilePath = filePath,
|
||||
ExportFormat = exportFormat,
|
||||
OverwriteExisting = true,
|
||||
ValidateExportData = true,
|
||||
GenerateReport = false,
|
||||
Description = $"导出所有路径到: {Path.GetFileName(filePath)}"
|
||||
};
|
||||
|
||||
// 创建并执行导出命令
|
||||
var exportCommand = new ExportPathCommand(exportParameters, _pathPlanningManager);
|
||||
var result = await exportCommand.ExecuteAsync();
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
var exportResult = (result as PathPlanningResult<ExportPathResult>)?.Data;
|
||||
if (exportResult != null)
|
||||
{
|
||||
AutoPathStatus = $"✅ 导出成功: {exportResult.ExportedCount} 个路径到 {Path.GetFileName(filePath)}";
|
||||
if (exportResult.FailedCount > 0)
|
||||
{
|
||||
AutoPathStatus += $" (失败 {exportResult.FailedCount} 个)";
|
||||
}
|
||||
LogManager.Info($"导出完成,文件大小: {exportResult.FileSizeMB:F2} MB");
|
||||
}
|
||||
else
|
||||
{
|
||||
AutoPathStatus = $"✅ 路径导出完成: {Path.GetFileName(filePath)}";
|
||||
}
|
||||
|
||||
PathFileStatus = "已导出";
|
||||
}
|
||||
else
|
||||
{
|
||||
AutoPathStatus = $"❌ 导出失败: {result.ErrorMessage}";
|
||||
PathFileStatus = "导出失败";
|
||||
LogManager.Error($"路径导出失败: {result.ErrorMessage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"导出路径异常: {ex.Message}", ex);
|
||||
AutoPathStatus = $"❌ 导出异常: {ex.Message}";
|
||||
PathFileStatus = "导出异常";
|
||||
}
|
||||
}, "导出路径");
|
||||
}
|
||||
|
||||
@ -819,13 +975,141 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
await SafeExecuteAsync(async () =>
|
||||
{
|
||||
// TODO: 实现另存为逻辑
|
||||
await Task.CompletedTask;
|
||||
AutoPathStatus = $"另存为路径: {SelectedPathRoute.Name}";
|
||||
PathFileStatus = "已保存";
|
||||
try
|
||||
{
|
||||
// 打开文件保存对话框
|
||||
var saveFileDialog = new SaveFileDialog
|
||||
{
|
||||
Title = $"另存为路径: {SelectedPathRoute?.Name}",
|
||||
Filter = "XML文件 (*.xml)|*.xml|JSON文件 (*.json)|*.json|所有文件 (*.*)|*.*",
|
||||
FilterIndex = 1,
|
||||
FileName = SelectedPathRoute?.Name?.Replace(" ", "_") ?? "路径",
|
||||
DefaultExt = "xml",
|
||||
AddExtension = true
|
||||
};
|
||||
|
||||
if (saveFileDialog.ShowDialog() == true)
|
||||
{
|
||||
var filePath = saveFileDialog.FileName;
|
||||
var extension = Path.GetExtension(filePath).ToLower();
|
||||
|
||||
// 确定导出格式
|
||||
var exportFormat = extension == ".json" ? ExportFormat.Json : ExportFormat.Xml;
|
||||
|
||||
// 查找当前选中路径对应的Core路径
|
||||
var coreRoute = _pathPlanningManager.Routes.FirstOrDefault(r => r.Name == SelectedPathRoute.Name);
|
||||
if (coreRoute != null)
|
||||
{
|
||||
// 创建导出参数 - 只导出当前选中的路径
|
||||
var exportParameters = new ExportPathParameters
|
||||
{
|
||||
PathsToExport = new System.Collections.Generic.List<PathRoute> { coreRoute },
|
||||
OutputFilePath = filePath,
|
||||
ExportFormat = exportFormat,
|
||||
OverwriteExisting = true,
|
||||
ValidateExportData = true,
|
||||
GenerateReport = false,
|
||||
Description = $"另存为路径: {SelectedPathRoute.Name}"
|
||||
};
|
||||
|
||||
// 创建并执行导出命令
|
||||
var exportCommand = new ExportPathCommand(exportParameters, _pathPlanningManager);
|
||||
var result = await exportCommand.ExecuteAsync();
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
var exportResult = (result as PathPlanningResult<ExportPathResult>)?.Data;
|
||||
if (exportResult != null)
|
||||
{
|
||||
AutoPathStatus = $"✅ 另存为成功: {SelectedPathRoute.Name} -> {Path.GetFileName(filePath)}";
|
||||
LogManager.Info($"另存为完成,文件大小: {exportResult.FileSizeMB:F2} MB");
|
||||
}
|
||||
else
|
||||
{
|
||||
AutoPathStatus = $"✅ 另存为完成: {Path.GetFileName(filePath)}";
|
||||
}
|
||||
|
||||
PathFileStatus = "已另存为";
|
||||
}
|
||||
else
|
||||
{
|
||||
AutoPathStatus = $"❌ 另存为失败: {result.ErrorMessage}";
|
||||
PathFileStatus = "另存为失败";
|
||||
LogManager.Error($"另存为失败: {result.ErrorMessage}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AutoPathStatus = $"❌ 找不到对应的Core路径: {SelectedPathRoute.Name}";
|
||||
PathFileStatus = "另存为失败";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"另存为路径异常: {ex.Message}", ex);
|
||||
AutoPathStatus = $"❌ 另存为异常: {ex.Message}";
|
||||
PathFileStatus = "另存为异常";
|
||||
}
|
||||
}, "另存为路径");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新路径集合显示
|
||||
/// </summary>
|
||||
private void RefreshPathRoutes()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_pathPlanningManager?.Routes != null)
|
||||
{
|
||||
// 清除现有的UI路径
|
||||
PathRoutes.Clear();
|
||||
|
||||
// 重新加载所有路径
|
||||
foreach (var coreRoute in _pathPlanningManager.Routes)
|
||||
{
|
||||
var pathViewModel = new PathRouteViewModel
|
||||
{
|
||||
Name = coreRoute.Name,
|
||||
Description = coreRoute.Description,
|
||||
IsActive = false
|
||||
};
|
||||
|
||||
// 转换路径点
|
||||
foreach (var corePoint in coreRoute.Points)
|
||||
{
|
||||
var wpfPoint = new PathPointViewModel
|
||||
{
|
||||
Name = corePoint.Name,
|
||||
X = corePoint.X,
|
||||
Y = corePoint.Y,
|
||||
Z = corePoint.Z,
|
||||
Type = corePoint.Type
|
||||
};
|
||||
pathViewModel.Points.Add(wpfPoint);
|
||||
}
|
||||
|
||||
PathRoutes.Add(pathViewModel);
|
||||
LogManager.Info($"RefreshPathRoutes: 添加路径ViewModel {coreRoute.Name} (Hash: {pathViewModel.GetHashCode()})");
|
||||
}
|
||||
|
||||
LogManager.Info($"已刷新路径集合显示,共 {PathRoutes.Count} 个路径");
|
||||
|
||||
// 调试:列出所有PathRoutes中的路径名称和哈希码
|
||||
for (int i = 0; i < PathRoutes.Count; i++)
|
||||
{
|
||||
var route = PathRoutes[i];
|
||||
LogManager.Info($" PathRoutes[{i}]: {route.Name} (Hash: {route.GetHashCode()}, Points: {route.Points.Count})");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"刷新路径集合失败: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
@ -1267,6 +1551,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
var pathViewModel = PathRoutes.FirstOrDefault(p => p.Name == e.Route.Name);
|
||||
if (pathViewModel != null)
|
||||
{
|
||||
// 检查路径点数量是否已经正确,避免重复处理
|
||||
if (pathViewModel.Points.Count == e.Route.Points.Count)
|
||||
{
|
||||
LogManager.Info($"路径点数量已正确({pathViewModel.Points.Count}),跳过重复更新");
|
||||
return;
|
||||
}
|
||||
|
||||
// 同步路径点数据
|
||||
pathViewModel.Points.Clear();
|
||||
foreach (var point in e.Route.Points)
|
||||
@ -1281,6 +1572,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
};
|
||||
pathViewModel.Points.Add(pointViewModel);
|
||||
}
|
||||
LogManager.Info($"已更新路径点列表,当前点数: {pathViewModel.Points.Count}");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Warning($"未找到对应的PathViewModel: {e.Route.Name}");
|
||||
}
|
||||
}, "处理路径点列表更新事件");
|
||||
}
|
||||
@ -1307,7 +1603,25 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
var pathViewModel = PathRoutes.FirstOrDefault(p => p.Name == e.NewRoute.Name);
|
||||
if (pathViewModel != null)
|
||||
{
|
||||
SelectedPathRoute = pathViewModel;
|
||||
// 只在真的不同时才设置,避免重复触发
|
||||
if (SelectedPathRoute != pathViewModel)
|
||||
{
|
||||
SelectedPathRoute = pathViewModel;
|
||||
LogManager.Info($"UI已同步选择路径: {e.NewRoute.Name}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Warning($"OnCurrentRouteChanged: UI中未找到路径 {e.NewRoute.Name},可能UI还未刷新");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 当前路径被设为null,清除UI选择
|
||||
if (SelectedPathRoute != null)
|
||||
{
|
||||
SelectedPathRoute = null;
|
||||
LogManager.Info("UI已清除路径选择");
|
||||
}
|
||||
}
|
||||
}, "处理当前路径变更事件");
|
||||
|
||||
122
src/UI/WPF/Views/AboutDialog.xaml
Normal file
122
src/UI/WPF/Views/AboutDialog.xaml
Normal file
@ -0,0 +1,122 @@
|
||||
<!--
|
||||
NavisworksTransport 关于对话框 - 采用与主界面一致的Navisworks 2026风格
|
||||
|
||||
功能说明:
|
||||
1. 显示插件版本信息和开发者信息
|
||||
2. 提供技术支持和联系方式
|
||||
3. 与主界面保持一致的视觉风格
|
||||
|
||||
设计原则:使用统一的蓝色主题和样式规范
|
||||
-->
|
||||
<Window x:Class="NavisworksTransport.UI.WPF.Views.AboutDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
Title="关于插件"
|
||||
Height="400"
|
||||
Width="500"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
|
||||
<Window.Resources>
|
||||
<!-- 引用共享的Navisworks 2026样式资源 -->
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/NavisworksTransportPlugin;component/src/UI/WPF/Resources/NavisworksStyles.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<Border Grid.Row="0"
|
||||
BorderBrush="#FFD4E7FF"
|
||||
BorderThickness="1"
|
||||
CornerRadius="0"
|
||||
Background="White"
|
||||
Margin="15,15,15,10">
|
||||
<StackPanel Margin="20">
|
||||
|
||||
<!-- 插件标题和版本 -->
|
||||
<Label Content="NavisworksTransport" Style="{StaticResource TitleStyle}"/>
|
||||
<Label Content="物流路径规划插件 v1.0" Style="{StaticResource VersionStyle}"/>
|
||||
|
||||
<!-- 分隔线 -->
|
||||
<Border Height="1"
|
||||
Background="#FFD4E7FF"
|
||||
Margin="0,15,0,20"/>
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<Grid Margin="0,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="适用版本:" Style="{StaticResource InfoLabelStyle}"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" Text="Autodesk Navisworks Manage 2026" Style="{StaticResource InfoTextStyle}"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="版本号:" Style="{StaticResource InfoLabelStyle}"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" Text="1.0.0" Style="{StaticResource InfoTextStyle}"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="发布日期:" Style="{StaticResource InfoLabelStyle}"/>
|
||||
<TextBlock Grid.Row="2" Grid.Column="1" Text="2024年8月" Style="{StaticResource InfoTextStyle}"/>
|
||||
|
||||
<Label Grid.Row="3" Grid.Column="0" Content="开发语言:" Style="{StaticResource InfoLabelStyle}"/>
|
||||
<TextBlock Grid.Row="3" Grid.Column="1" Text="C# .NET Framework 4.8" Style="{StaticResource InfoTextStyle}"/>
|
||||
|
||||
<Label Grid.Row="4" Grid.Column="0" Content="UI框架:" Style="{StaticResource InfoLabelStyle}"/>
|
||||
<TextBlock Grid.Row="4" Grid.Column="1" Text="WPF + MVVM" Style="{StaticResource InfoTextStyle}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 功能描述 -->
|
||||
<TextBlock Text="专为Navisworks 2026设计的物流路径规划插件。支持3D路径规划、A*寻路算法、动画生成、碰撞检测等功能。通过直观的用户界面,帮助用户在建筑信息模型中进行高效的物流运输规划和冲突检测。"
|
||||
Style="{StaticResource DescriptionStyle}"/>
|
||||
|
||||
<!-- 主要特性 -->
|
||||
<TextBlock Style="{StaticResource DescriptionStyle}" Margin="20,10">
|
||||
<Run Text="主要特性:" FontWeight="Medium" Foreground="#FF2B579A"/>
|
||||
<LineBreak/>
|
||||
<Run Text="• 智能路径规划与A*算法优化"/>
|
||||
<LineBreak/>
|
||||
<Run Text="• 实时碰撞检测与冲突分析"/>
|
||||
<LineBreak/>
|
||||
<Run Text="• 流畅的3D动画演示"/>
|
||||
<LineBreak/>
|
||||
<Run Text="• 完整的物流类别管理系统"/>
|
||||
</TextBlock>
|
||||
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<Border Grid.Row="1"
|
||||
BorderBrush="#FFD4E7FF"
|
||||
BorderThickness="1"
|
||||
CornerRadius="0"
|
||||
Background="#FFF8FBFF"
|
||||
Margin="15,0,15,15"
|
||||
Padding="15,10">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Right">
|
||||
<Button Content="关闭"
|
||||
Click="CloseButton_Click"
|
||||
Style="{StaticResource ActionButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
24
src/UI/WPF/Views/AboutDialog.xaml.cs
Normal file
24
src/UI/WPF/Views/AboutDialog.xaml.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace NavisworksTransport.UI.WPF.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// AboutDialog.xaml 的交互逻辑
|
||||
/// 插件关于对话框,显示版本信息和开发者信息
|
||||
/// </summary>
|
||||
public partial class AboutDialog : Window
|
||||
{
|
||||
public AboutDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭按钮点击事件
|
||||
/// </summary>
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -19,79 +19,35 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
d:DesignHeight="700" d:DesignWidth="480">
|
||||
|
||||
<UserControl.Resources>
|
||||
<!-- 转换器资源 -->
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisConverter"/>
|
||||
|
||||
<!-- Navisworks 2026 风格样式定义 -->
|
||||
<Style x:Key="SectionHeaderStyle" TargetType="Label">
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="0,5,0,2"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FF4472C4"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="10,5"/>
|
||||
<Setter Property="Margin" Value="0,0,10,0"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SecondaryButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FFE7F1FF"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="BorderBrush" Value="#FF4472C4"/>
|
||||
<Setter Property="Padding" Value="8,4"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="StatusTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="#FF666666"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
</Style>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/NavisworksTransportPlugin;component/src/UI/WPF/Resources/NavisworksStyles.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- 转换器资源 -->
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisConverter"/>
|
||||
|
||||
<Style x:Key="ParameterLabelStyle" TargetType="Label">
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="0,0,5,0"/>
|
||||
</Style>
|
||||
<!-- 动画控制页面特有的样式 -->
|
||||
<Style x:Key="ProgressBarStyle" TargetType="ProgressBar">
|
||||
<Setter Property="Height" Value="20"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksSecondaryBrush}"/>
|
||||
<Setter Property="Background" Value="{StaticResource NavisworksButtonBrush}"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource NavisworksPrimaryBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ParameterInputStyle" TargetType="TextBox">
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="Margin" Value="5,2"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="UnitLabelStyle" TargetType="Label">
|
||||
<Setter Property="Width" Value="30"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="2,0,0,0"/>
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="#FF666666"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ProgressBarStyle" TargetType="ProgressBar">
|
||||
<Setter Property="Height" Value="20"/>
|
||||
<Setter Property="Foreground" Value="#FF4472C4"/>
|
||||
<Setter Property="Background" Value="#FFE7F1FF"/>
|
||||
<Setter Property="BorderBrush" Value="#FF2B579A"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SliderStyle" TargetType="Slider">
|
||||
<Setter Property="Foreground" Value="#FF4472C4"/>
|
||||
<Setter Property="Height" Value="20"/>
|
||||
</Style>
|
||||
<Style x:Key="SliderStyle" TargetType="Slider">
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksSecondaryBrush}"/>
|
||||
<Setter Property="Height" Value="20"/>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
|
||||
<StackPanel>
|
||||
|
||||
<!-- 区域1: 动画参数设置 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="动画参数设置" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -127,7 +83,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
</Border>
|
||||
|
||||
<!-- 区域2: 碰撞检测参数 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="碰撞检测参数" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -220,7 +176,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
</Border>
|
||||
|
||||
<!-- 区域3: 生成动画 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="生成动画" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -263,7 +219,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Grid.Column="0" Content="动画路径:" Style="{StaticResource ParameterLabelStyle}" Width="80"/>
|
||||
<Label Grid.Column="0" Content="移动路径:" Style="{StaticResource ParameterLabelStyle}" Width="80"/>
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding CurrentPathRoute.Name, StringFormat='当前路径: {0}', TargetNullValue='当前路径: 未选择'}"
|
||||
VerticalAlignment="Center"
|
||||
@ -295,7 +251,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
</StackPanel>
|
||||
|
||||
<!-- 生成状态提示 -->
|
||||
<TextBlock Text="提示:需要同时选择移动物体和动画路径才能生成动画"
|
||||
<TextBlock Text="提示:需要同时选择移动物体和移动路径才能生成动画"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Foreground="#FF666666"
|
||||
Margin="0,5,0,0"
|
||||
@ -304,7 +260,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
</Border>
|
||||
|
||||
<!-- 区域4: 播放控制 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="播放控制" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -338,7 +294,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Grid.Column="0" Content="进度:" Width="50" VerticalAlignment="Center"/>
|
||||
<Label Grid.Column="0" Content="播放进度:" Width="50" VerticalAlignment="Center"/>
|
||||
<ProgressBar Grid.Column="1"
|
||||
Value="{Binding AnimationProgress}"
|
||||
Style="{StaticResource ProgressBarStyle}"
|
||||
@ -363,7 +319,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
</Border>
|
||||
|
||||
<!-- 区域5: 碰撞检测 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="碰撞检测" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -393,7 +349,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
</Border>
|
||||
|
||||
<!-- 区域6: 动画预览和操作指南 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,0" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,0" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="动画预览与操作指南" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -417,16 +373,16 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
|
||||
<!-- 操作提示 -->
|
||||
<StackPanel Margin="0,5,0,0">
|
||||
<TextBlock Text="• 确保已在路径编辑页签中选择有效的路径进行动画"
|
||||
<TextBlock Text="• 确保已在路径编辑页签中选择了有效的路径"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="0,2"/>
|
||||
<TextBlock Text="• 动画将沿着当前选中的路径创建相机跟随视点序列"
|
||||
<TextBlock Text="• 动画将沿着当前选中的路径创建"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="0,2"/>
|
||||
<TextBlock Text="• 碰撞检测会在路径上模拟运输过程中的冲突检测"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="0,2"/>
|
||||
<TextBlock Text="• 动画播放后可在Navisworks视点管理器中手动控制播放"
|
||||
<TextBlock Text="• 碰撞检测后可在ClashDetective插件中查看碰撞结果"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="0,2"/>
|
||||
</StackPanel>
|
||||
|
||||
145
src/UI/WPF/Views/HelpDialog.xaml
Normal file
145
src/UI/WPF/Views/HelpDialog.xaml
Normal file
@ -0,0 +1,145 @@
|
||||
<!--
|
||||
NavisworksTransport 帮助对话框 - 采用与主界面一致的Navisworks 2026风格
|
||||
|
||||
功能说明:
|
||||
1. 显示插件详细使用说明
|
||||
2. 提供操作指南和功能介绍
|
||||
3. 与主界面保持一致的视觉风格
|
||||
|
||||
设计原则:使用统一的蓝色主题和样式规范
|
||||
-->
|
||||
<Window x:Class="NavisworksTransport.UI.WPF.Views.HelpDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
Title="插件帮助"
|
||||
Height="500"
|
||||
Width="650"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
|
||||
<Window.Resources>
|
||||
<!-- 引用共享的Navisworks 2026样式资源 -->
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/NavisworksTransportPlugin;component/src/UI/WPF/Resources/NavisworksStyles.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- 帮助对话框专用样式 -->
|
||||
<Style x:Key="SubSectionHeaderStyle" TargetType="Label">
|
||||
<Setter Property="FontWeight" Value="Normal"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksSecondaryBrush}"/>
|
||||
<Setter Property="Padding" Value="0,6,0,2"/>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<Border Grid.Row="0"
|
||||
BorderBrush="#FFD4E7FF"
|
||||
BorderThickness="1"
|
||||
CornerRadius="0"
|
||||
Background="White"
|
||||
Margin="15,15,15,10">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto"
|
||||
Padding="15">
|
||||
<StackPanel>
|
||||
|
||||
<Label Content="NavisworksTransport 物流路径规划插件"
|
||||
Style="{StaticResource SectionHeaderStyle}"
|
||||
FontSize="16"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,10"/>
|
||||
|
||||
<!-- 分层管理 -->
|
||||
<Label Content="1. 分层管理" Style="{StaticResource SubSectionHeaderStyle}"/>
|
||||
<TextBlock Text="• 控制模型各层级的可见性和透明度"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 管理物流相关模型组件的显示状态"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 提供快速隐藏/显示功能,优化建模环境"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
|
||||
<!-- 类别设置 -->
|
||||
<Label Content="2. 类别设置" Style="{StaticResource SubSectionHeaderStyle}"/>
|
||||
<TextBlock Text="• 设置模型元素的物流类别属性(门、电梯、楼梯、通道等)"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 管理可通行性和障碍物标记"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 配置装卸区、停车区、检查点等物流功能区域"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
|
||||
<!-- 路径编辑 -->
|
||||
<Label Content="3. 路径编辑" Style="{StaticResource SubSectionHeaderStyle}"/>
|
||||
<TextBlock Text="• 自动路径规划:设置起终点,输入车辆尺寸,自动生成最优路径"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 手动路径创建:在3D视图中点击创建自定义路径"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 路径管理:新建、删除、重命名、导入导出路径文件"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 路径编辑:添加、删除、调整路径点位置"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
|
||||
<!-- 检测动画 -->
|
||||
<Label Content="4. 检测动画" Style="{StaticResource SubSectionHeaderStyle}"/>
|
||||
<TextBlock Text="• 生成沿路径的运输动画,支持自定义速度和帧率"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 运行碰撞检测,识别路径中的潜在冲突"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 播放控制:开始、暂停、停止动画"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 查看详细的碰撞检测报告"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
|
||||
<!-- 系统管理 -->
|
||||
<Label Content="5. 系统管理" Style="{StaticResource SubSectionHeaderStyle}"/>
|
||||
<TextBlock Text="• 日志管理:查看、清空、导出系统运行日志"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 插件设置:配置选项和功能开关"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 系统信息:查看插件版本、内存使用和性能状态"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="• 性能监控:生成性能报告和优化建议"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
|
||||
<!-- 使用提示 -->
|
||||
<Label Content="使用提示" Style="{StaticResource SubSectionHeaderStyle}" Margin="0,15,0,5"/>
|
||||
<TextBlock Text="1. 首次使用建议先在类别设置中标记物流相关的模型元素"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="2. 路径规划时需要确保起终点设在可通行的模型上"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="3. 自动路径规划需要合理设置车辆尺寸和安全间隙"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
<TextBlock Text="4. 碰撞检测结果可在ClashDetective插件中查看详情"
|
||||
Style="{StaticResource DialogContentTextStyle}"/>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<Border Grid.Row="1"
|
||||
BorderBrush="#FFD4E7FF"
|
||||
BorderThickness="1"
|
||||
CornerRadius="0"
|
||||
Background="#FFF8FBFF"
|
||||
Margin="15,0,15,15"
|
||||
Padding="15,10">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Right">
|
||||
<Button Content="关闭"
|
||||
Click="CloseButton_Click"
|
||||
Style="{StaticResource ActionButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
24
src/UI/WPF/Views/HelpDialog.xaml.cs
Normal file
24
src/UI/WPF/Views/HelpDialog.xaml.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace NavisworksTransport.UI.WPF.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// HelpDialog.xaml 的交互逻辑
|
||||
/// 插件帮助对话框,显示详细的使用说明和操作指南
|
||||
/// </summary>
|
||||
public partial class HelpDialog : Window
|
||||
{
|
||||
public HelpDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭按钮点击事件
|
||||
/// </summary>
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -19,47 +19,22 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
|
||||
d:DesignHeight="700" d:DesignWidth="420">
|
||||
|
||||
<UserControl.Resources>
|
||||
<!-- 转换器资源 -->
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisConverter"/>
|
||||
<converters:IndexConverter x:Key="IndexConverter"/>
|
||||
|
||||
<!-- Navisworks 2026 风格样式定义 -->
|
||||
<Style x:Key="SectionHeaderStyle" TargetType="Label">
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="0,5,0,2"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FF4472C4"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="10,5"/>
|
||||
<Setter Property="Margin" Value="0,0,10,0"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SecondaryButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FFE7F1FF"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="BorderBrush" Value="#FF4472C4"/>
|
||||
<Setter Property="Padding" Value="8,4"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="StatusTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="#FF666666"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
</Style>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/NavisworksTransportPlugin;component/src/UI/WPF/Resources/NavisworksStyles.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- 转换器资源 -->
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisConverter"/>
|
||||
<converters:IndexConverter x:Key="IndexConverter"/>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
|
||||
<StackPanel>
|
||||
|
||||
<!-- 区域1: 楼层属性设置(仅保留手动设置部分) -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="楼层属性设置" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -118,10 +93,10 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 区域2: 模型分层预览与保存 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<!-- 区域2: 分层预览与保存 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="模型分层预览与保存" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<Label Content="分层预览与保存" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
<!-- 分层策略和深度选择 -->
|
||||
<Grid Margin="0,5,0,10">
|
||||
@ -152,7 +127,7 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
|
||||
ItemsSource="{Binding DepthOptions}"
|
||||
Margin="5,2" IsEnabled="{Binding IsNotProcessing}"/>
|
||||
<Button Grid.Column="4"
|
||||
Content="预览分层"
|
||||
Content="预览"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Command="{Binding PreviewSplitCommand}"
|
||||
IsEnabled="{Binding CanPreviewSplit}"
|
||||
@ -167,13 +142,13 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
|
||||
</Grid>
|
||||
|
||||
<!-- 导出选项设置 -->
|
||||
<Expander Header="导出选项设置" IsExpanded="False" Margin="0,5,0,5">
|
||||
<Expander Header="NWD文件导出选项" IsExpanded="False" Margin="0,5,0,5">
|
||||
<StackPanel Margin="10,10,0,5">
|
||||
<TextBlock Text="配置NWD文件导出选项(对应Navisworks导出对话框选项)"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="0,0,0,8"/>
|
||||
<StackPanel>
|
||||
<CheckBox Content="嵌入 ReCap 和纹理数据"
|
||||
<CheckBox Content="嵌入ReCap和纹理数据"
|
||||
IsChecked="{Binding EmbedXrefs}"
|
||||
Margin="0,0,0,5"
|
||||
ToolTip="将外部引用和纹理数据嵌入到导出的NWD文件中"/>
|
||||
@ -186,20 +161,10 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
|
||||
IsChecked="{Binding PreventObjectPropertyExport}"
|
||||
Margin="0,0,0,5"
|
||||
ToolTip="导出时不包含对象的属性信息,可减小文件大小"/>
|
||||
<TextBlock Text="注:隐藏项目将自动排除(确保分层效果)"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Foreground="#FF666666"
|
||||
FontStyle="Italic"
|
||||
Margin="0,8,0,0"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Expander>
|
||||
|
||||
<!-- 说明文字 -->
|
||||
<TextBlock Text="点击[分层保存]时将弹出文件选择对话框,选择保存位置"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="0,0,0,5"/>
|
||||
|
||||
<!-- 分层预览结果和操作按钮 -->
|
||||
<GroupBox Header="分层预览结果" Margin="0,10,0,0" MinHeight="200">
|
||||
<Grid>
|
||||
@ -235,7 +200,7 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
|
||||
<StackPanel Grid.Row="0"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{Binding ShowPreviewPrompt, Converter={StaticResource BoolToVisConverter}}">
|
||||
<TextBlock Text="点击[预览分层]生成分层列表,或查看错误信息"
|
||||
<TextBlock Text="点击[预览]生成分层列表,或查看错误信息"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
@ -256,7 +221,7 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
|
||||
</Border>
|
||||
|
||||
<!-- 区域3: 选择集保存 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="选择集保存" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -278,20 +243,6 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
|
||||
FontWeight="SemiBold"
|
||||
Foreground="#FF2B579A"
|
||||
Margin="0,0,0,10"/>
|
||||
|
||||
<!-- 保存选项 -->
|
||||
<StackPanel Grid.Row="2"
|
||||
Orientation="Horizontal"
|
||||
Margin="0,0,0,0">
|
||||
<CheckBox Content="包含子节点"
|
||||
IsChecked="{Binding IncludeChildNodes}"
|
||||
Margin="0,0,15,0"/>
|
||||
<CheckBox Content="保留材质贴图"
|
||||
IsChecked="{Binding PreserveMaterials}"
|
||||
Margin="0,0,15,0"/>
|
||||
<CheckBox Content="生成预览图"
|
||||
IsChecked="{Binding GeneratePreview}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- 保存按钮区域 -->
|
||||
@ -317,7 +268,7 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
|
||||
</Border>
|
||||
|
||||
<!-- 进度和状态区域 -->
|
||||
<Border BorderBrush="#FFE0E0E0" BorderThickness="1" CornerRadius="4" Padding="12"
|
||||
<Border BorderBrush="#FFE0E0E0" BorderThickness="1" CornerRadius="0" Padding="12"
|
||||
Visibility="{Binding IsProcessing, Converter={StaticResource BoolToVisConverter}}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding CurrentOperationText}"
|
||||
|
||||
@ -20,69 +20,24 @@ NavisworksTransport 类别设置页签视图 - 参考分层管理页签的设计
|
||||
d:DesignHeight="700" d:DesignWidth="480">
|
||||
|
||||
<UserControl.Resources>
|
||||
<!-- 转换器资源 -->
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisConverter"/>
|
||||
<converters:IndexConverter x:Key="IndexConverter"/>
|
||||
|
||||
<!-- Navisworks 2026 风格样式定义 -->
|
||||
<Style x:Key="SectionHeaderStyle" TargetType="Label">
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="0,5,0,2"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FF4472C4"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="10,5"/>
|
||||
<Setter Property="Margin" Value="0,0,10,0"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SecondaryButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FFE7F1FF"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="BorderBrush" Value="#FF4472C4"/>
|
||||
<Setter Property="Padding" Value="8,4"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="StatusTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="#FF666666"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ParameterLabelStyle" TargetType="Label">
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="0,0,5,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ParameterInputStyle" TargetType="TextBox">
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="Margin" Value="5,2"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="UnitLabelStyle" TargetType="Label">
|
||||
<Setter Property="Width" Value="30"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="2,0,0,0"/>
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="#FF666666"/>
|
||||
</Style>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/NavisworksTransportPlugin;component/src/UI/WPF/Resources/NavisworksStyles.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- 转换器资源 -->
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisConverter"/>
|
||||
<converters:IndexConverter x:Key="IndexConverter"/>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
|
||||
<StackPanel>
|
||||
|
||||
<!-- 区域1: 模型选择和类别属性设置(整合区域) -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<!-- 区域1: 物流属性设置 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="模型选择与类别属性设置" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<Label Content="物流属性设置" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
<!-- 模型选择状态显示 -->
|
||||
<Grid Margin="0,5,0,15">
|
||||
@ -96,23 +51,10 @@ NavisworksTransport 类别设置页签视图 - 参考分层管理页签的设计
|
||||
FontWeight="SemiBold"
|
||||
Foreground="#FF2B579A"
|
||||
Margin="0,0,0,5"/>
|
||||
|
||||
<StackPanel Grid.Row="1"
|
||||
Orientation="Horizontal"
|
||||
Margin="0,0,0,0">
|
||||
<Button Content="刷新选择"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Command="{Binding RefreshSelectionCommand}"
|
||||
ToolTip="检查当前在主界面中选择的模型"/>
|
||||
<TextBlock Text="提示:请在主界面中选择需要设置属性的模型,然后点击刷新选择"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="10,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- 类别属性设置 -->
|
||||
<GroupBox Header="物流属性配置" Margin="0,5,0,0">
|
||||
<GroupBox Header="物流属性" Margin="0,5,0,0">
|
||||
<StackPanel Margin="10">
|
||||
<!-- 第一行:物流类型和可通行性 -->
|
||||
<Grid Margin="0,0,0,10">
|
||||
@ -202,7 +144,7 @@ NavisworksTransport 类别设置页签视图 - 参考分层管理页签的设计
|
||||
ToolTip="速度限制(米/秒)"/>
|
||||
<Label Grid.Column="2" Content="米/秒" Style="{StaticResource UnitLabelStyle}" Width="40"/>
|
||||
<TextBlock Grid.Column="3"
|
||||
Text="默认推荐值:通道 0.8m/s,电梯 0.5m/s,楼梯 0.3m/s"
|
||||
Text="推荐值:通道 0.8m/s,电梯 0.5m/s,楼梯 0.3m/s"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="10,0,0,0"/>
|
||||
@ -227,10 +169,10 @@ NavisworksTransport 类别设置页签视图 - 参考分层管理页签的设计
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 区域2: 物流模型列表管理 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<!-- 区域2: 物流模型列表 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="物流模型列表管理" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<Label Content="物流模型列表" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
<!-- 列表刷新控制 -->
|
||||
<Grid Margin="0,5,0,10">
|
||||
@ -286,7 +228,7 @@ NavisworksTransport 类别设置页签视图 - 参考分层管理页签的设计
|
||||
</Border>
|
||||
|
||||
<!-- 区域3: 可见性控制 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="显示模式控制" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -313,7 +255,7 @@ NavisworksTransport 类别设置页签视图 - 参考分层管理页签的设计
|
||||
</Border>
|
||||
|
||||
<!-- 状态显示区域 -->
|
||||
<Border BorderBrush="#FFE0E0E0" BorderThickness="1" CornerRadius="4" Padding="12"
|
||||
<Border BorderBrush="#FFE0E0E0" BorderThickness="1" CornerRadius="0" Padding="12"
|
||||
Visibility="{Binding IsProcessing, Converter={StaticResource BoolToVisConverter}}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding StatusText}"
|
||||
@ -328,7 +270,7 @@ NavisworksTransport 类别设置页签视图 - 参考分层管理页签的设计
|
||||
</Border>
|
||||
|
||||
<!-- 底部状态栏 -->
|
||||
<Border BorderBrush="#FFE0E0E0" BorderThickness="1" CornerRadius="4" Padding="8"
|
||||
<Border BorderBrush="#FFE0E0E0" BorderThickness="1" CornerRadius="0" Padding="8"
|
||||
Background="#FFF8F9FA" Margin="0,5,0,0">
|
||||
<TextBlock Text="{Binding StatusText}"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
|
||||
@ -3,8 +3,8 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
|
||||
|
||||
功能说明:
|
||||
1. 自动路径规划:起终点选择、车辆尺寸参数(长宽高)、安全间隙设置
|
||||
2. 路径列表管理:新建、删除、重命名路径,显示路径状态
|
||||
3. 手动路径编辑:开始编辑、结束编辑、清空路径、路径点管理
|
||||
2. 路径列表:新建、删除、重命名路径,显示路径状态
|
||||
3. 路径编辑:开始编辑、结束编辑、清空路径、路径点管理
|
||||
4. 路径文件管理:导入、导出、另存为操作和状态显示
|
||||
|
||||
设计原则:与Navisworks 2026风格一致,480像素宽度,现代化UI布局,采用GroupBox分组
|
||||
@ -19,74 +19,21 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
|
||||
d:DesignHeight="800" d:DesignWidth="480">
|
||||
|
||||
<UserControl.Resources>
|
||||
<!-- 转换器资源 -->
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisConverter"/>
|
||||
|
||||
<!-- Navisworks 2026 风格样式定义 -->
|
||||
<Style x:Key="SectionHeaderStyle" TargetType="Label">
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="0,5,0,2"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FF4472C4"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="10,5"/>
|
||||
<Setter Property="Margin" Value="0,0,10,0"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SecondaryButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FFE7F1FF"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="BorderBrush" Value="#FF4472C4"/>
|
||||
<Setter Property="Padding" Value="8,4"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="StatusTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="#FF666666"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ParameterLabelStyle" TargetType="Label">
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="0,0,5,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ParameterInputStyle" TargetType="TextBox">
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="Margin" Value="5,2"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="UnitLabelStyle" TargetType="Label">
|
||||
<Setter Property="Width" Value="30"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="2,0,0,0"/>
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="#FF666666"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ReadOnlyTextBoxStyle" TargetType="TextBox">
|
||||
<Setter Property="IsReadOnly" Value="True"/>
|
||||
<Setter Property="Background" Value="#FFF5F5F5"/>
|
||||
<Setter Property="BorderBrush" Value="#FFCCCCCC"/>
|
||||
<Setter Property="Padding" Value="5,3"/>
|
||||
<Setter Property="Margin" Value="5,2"/>
|
||||
</Style>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/NavisworksTransportPlugin;component/src/UI/WPF/Resources/NavisworksStyles.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- 转换器资源 -->
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisConverter"/>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
|
||||
<StackPanel>
|
||||
|
||||
<!-- 区域1: 自动路径规划 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="自动路径规划" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -185,16 +132,16 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
|
||||
</Border>
|
||||
|
||||
<!-- 区域2: 路径列表管理 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="路径列表管理" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<Label Content="路径列表" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
<!-- 路径管理按钮 -->
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,10">
|
||||
<Button Content="新建路径"
|
||||
<Button Content="手动创建"
|
||||
Command="{Binding NewPathCommand}"
|
||||
Style="{StaticResource ActionButtonStyle}"/>
|
||||
<Button Content="删除路径"
|
||||
<Button Content="删除"
|
||||
Command="{Binding DeletePathCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
IsEnabled="{Binding SelectedPathRoute, Converter={x:Static converters:BoolToVisibilityConverter.IsNotNullToBoolConverter}}"/>
|
||||
@ -229,22 +176,22 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 区域3: 手动路径编辑 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<!-- 区域3: 路径编辑 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="手动路径编辑" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<Label Content="路径编辑" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
<!-- 编辑控制按钮 -->
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,10">
|
||||
<Button Content="开始编辑"
|
||||
<Button Content="开始"
|
||||
Command="{Binding StartEditCommand}"
|
||||
Style="{StaticResource ActionButtonStyle}"
|
||||
IsEnabled="{Binding CanExecuteStartEdit}"/>
|
||||
<Button Content="结束编辑"
|
||||
<Button Content="结束"
|
||||
Command="{Binding EndEditCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
IsEnabled="{Binding CanExecuteEndEdit}"/>
|
||||
<Button Content="清空路径"
|
||||
<Button Content="清空"
|
||||
Command="{Binding ClearPathCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Background="#FFFFE6E6"
|
||||
@ -308,16 +255,16 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
|
||||
</Border>
|
||||
|
||||
<!-- 区域4: 路径文件管理 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="路径文件管理" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
<!-- 文件操作按钮 -->
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,10">
|
||||
<Button Content="导入路径"
|
||||
<Button Content="导入"
|
||||
Command="{Binding ImportPathCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"/>
|
||||
<Button Content="导出路径"
|
||||
<Button Content="导出"
|
||||
Command="{Binding ExportPathCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
IsEnabled="{Binding CanExecuteExportPath}"/>
|
||||
@ -346,7 +293,7 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
|
||||
</Border>
|
||||
|
||||
<!-- 区域5: 3D交互指南 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,0" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,0" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="3D交互操作指南" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -362,10 +309,10 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="10,2"/>
|
||||
|
||||
<TextBlock Text="手动路径编辑:"
|
||||
<TextBlock Text="路径编辑:"
|
||||
FontWeight="SemiBold"
|
||||
Margin="0,8,0,2"/>
|
||||
<TextBlock Text="• 选择路径后点击"开始编辑"进入编辑模式"
|
||||
<TextBlock Text="• 选择路径后点击"编辑"进入编辑模式"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="10,2"/>
|
||||
<TextBlock Text="• 在3D视图中点击可通行的物流模型添加路径点"
|
||||
@ -374,7 +321,7 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
|
||||
<TextBlock Text="• 使用列表中的"删除"按钮移除不需要的路径点"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="10,2"/>
|
||||
<TextBlock Text="• 编辑完成后点击"结束编辑"保存修改"
|
||||
<TextBlock Text="• 编辑完成后点击"结束"保存修改"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="10,2"/>
|
||||
</StackPanel>
|
||||
|
||||
@ -18,61 +18,32 @@ NavisworksTransport 系统管理页签视图 - 采用与其他页签一致的Nav
|
||||
d:DesignHeight="800" d:DesignWidth="480">
|
||||
|
||||
<UserControl.Resources>
|
||||
<!-- Navisworks 2026 风格样式定义 -->
|
||||
<Style x:Key="SectionHeaderStyle" TargetType="Label">
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="0,5,0,2"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FF4472C4"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="10,5"/>
|
||||
<Setter Property="Margin" Value="0,0,10,0"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SecondaryButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FFE7F1FF"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="BorderBrush" Value="#FF4472C4"/>
|
||||
<Setter Property="Padding" Value="8,4"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="StatusTextStyle" TargetType="Label">
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="#FF666666"/>
|
||||
</Style>
|
||||
<!-- 引用共享的Navisworks 2026样式资源 -->
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/NavisworksTransportPlugin;component/src/UI/WPF/Resources/NavisworksStyles.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- 系统管理页面特有的样式 -->
|
||||
<Style x:Key="InfoTextStyle" TargetType="Label">
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksTextBrush}"/>
|
||||
<Setter Property="Padding" Value="0,2"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="InfoTextStyle" TargetType="Label">
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="#FF666666"/>
|
||||
<Setter Property="Padding" Value="0,2"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ParameterLabelStyle" TargetType="Label">
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="0,0,5,0"/>
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="StatusLabelStyle" TargetType="Label">
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="0,2"/>
|
||||
</Style>
|
||||
<Style x:Key="StatusLabelStyle" TargetType="Label">
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="FontWeight" Value="Normal"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource NavisworksPrimaryBrush}"/>
|
||||
<Setter Property="Padding" Value="0,2"/>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
|
||||
<StackPanel>
|
||||
<!-- 区域1: 日志管理 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="日志管理" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -97,7 +68,7 @@ NavisworksTransport 系统管理页签视图 - 采用与其他页签一致的Nav
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Grid.Column="0" Content="日志级别:" Style="{StaticResource ParameterLabelStyle}" Width="60"/>
|
||||
<Label Grid.Column="0" Content="日志级别:" Style="{StaticResource ParameterLabelStyle}" Width="80"/>
|
||||
<ComboBox Grid.Column="1"
|
||||
ItemsSource="{Binding LogLevels}"
|
||||
SelectedItem="{Binding SelectedLogLevel}"
|
||||
@ -113,7 +84,7 @@ NavisworksTransport 系统管理页签视图 - 采用与其他页签一致的Nav
|
||||
</Border>
|
||||
|
||||
<!-- 区域2: 插件设置 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="插件设置" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -148,7 +119,7 @@ NavisworksTransport 系统管理页签视图 - 采用与其他页签一致的Nav
|
||||
</Border>
|
||||
|
||||
<!-- 区域3: 系统信息 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="系统信息" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -194,7 +165,7 @@ NavisworksTransport 系统管理页签视图 - 采用与其他页签一致的Nav
|
||||
</Border>
|
||||
|
||||
<!-- 区域4: 性能监控 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,0" Padding="12">
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,0" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="性能监控" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user