diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index 848666d..110cc46 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -154,7 +154,8 @@
"Bash(\"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\MSBuild.exe\" AStarTestRunner.csproj /p:Configuration=Debug /p:Platform=AnyCPU)",
"Bash(\"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\MSBuild.exe\" AStarTestRunner.csproj)",
"Bash(\"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\MSBuild.exe\" NavisworksTransport.UnitTests.csproj)",
- "Bash(\"bin\\Debug\\AStarTestRunner.exe\")"
+ "Bash(\"bin\\Debug\\AStarTestRunner.exe\")",
+ "Bash(git restore:*)"
],
"deny": [],
"additionalDirectories": [
diff --git a/NavisworksTransportPlugin.csproj b/NavisworksTransportPlugin.csproj
index 04cb8b4..1aed6ee 100644
--- a/NavisworksTransportPlugin.csproj
+++ b/NavisworksTransportPlugin.csproj
@@ -227,15 +227,12 @@
-
-
-
diff --git a/src/UI/WPF/Collections/VirtualizedObservableCollection.cs b/src/UI/WPF/Collections/VirtualizedObservableCollection.cs
deleted file mode 100644
index 65f6a3b..0000000
--- a/src/UI/WPF/Collections/VirtualizedObservableCollection.cs
+++ /dev/null
@@ -1,982 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.ComponentModel;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Windows.Data;
-using NavisworksTransport.UI.WPF.Services;
-using NavisworksTransport.Utils;
-
-namespace NavisworksTransport.UI.WPF.Collections
-{
- ///
- /// 虚拟化的可观察集合 - 为大数据集合提供高性能的WPF绑定支持
- /// 只在内存中保存可见项目,按需加载数据,支持智能预加载和缓存
- ///
- /// 集合元素类型
- public class VirtualizedObservableCollection : IList, INotifyCollectionChanged, INotifyPropertyChanged
- {
- #region 字段和属性
-
- // 数据提供器
- private readonly IVirtualDataProvider _dataProvider;
- private readonly DataBindingPerformanceMonitor _performanceMonitor;
-
- // 虚拟化设置
- private int _pageSize = 100;
- private int _cacheSize = 500;
- private int _preloadDistance = 50;
-
- // 缓存管理
- private readonly Dictionary _itemCache = new Dictionary();
- private readonly Dictionary _cacheTimestamps = new Dictionary();
- private readonly object _cacheLock = new object();
-
- // 状态管理
- private int _totalCount = 0;
- private bool _isLoading = false;
- private readonly object _loadingLock = new object();
-
- // 视口管理
- private int _viewportStart = 0;
- private int _viewportSize = 20;
-
- ///
- /// 集合变更事件
- ///
- public event NotifyCollectionChangedEventHandler CollectionChanged;
-
- ///
- /// 属性变更事件
- ///
- public event PropertyChangedEventHandler PropertyChanged;
-
- ///
- /// 总项目数量
- ///
- public int Count
- {
- get => _totalCount;
- private set
- {
- if (_totalCount != value)
- {
- _totalCount = value;
- OnPropertyChanged(nameof(Count));
- }
- }
- }
-
- ///
- /// 页面大小 - 每次从数据提供器加载的项目数量
- ///
- public int PageSize
- {
- get => _pageSize;
- set
- {
- if (value > 0 && _pageSize != value)
- {
- _pageSize = value;
- OnPropertyChanged(nameof(PageSize));
- InvalidateCache();
- }
- }
- }
-
- ///
- /// 缓存大小 - 内存中保存的最大项目数量
- ///
- public int CacheSize
- {
- get => _cacheSize;
- set
- {
- if (value > 0 && _cacheSize != value)
- {
- _cacheSize = value;
- OnPropertyChanged(nameof(CacheSize));
- CleanupCache();
- }
- }
- }
-
- ///
- /// 预加载距离 - 距离视口边缘多远开始预加载
- ///
- public int PreloadDistance
- {
- get => _preloadDistance;
- set
- {
- if (value >= 0 && _preloadDistance != value)
- {
- _preloadDistance = value;
- OnPropertyChanged(nameof(PreloadDistance));
- }
- }
- }
-
- ///
- /// 当前视口起始位置
- ///
- public int ViewportStart
- {
- get => _viewportStart;
- set
- {
- if (_viewportStart != value)
- {
- _viewportStart = Math.Max(0, Math.Min(value, Math.Max(0, Count - _viewportSize)));
- OnPropertyChanged(nameof(ViewportStart));
- TriggerPreload();
- }
- }
- }
-
- ///
- /// 视口大小 - 可见区域的项目数量
- ///
- public int ViewportSize
- {
- get => _viewportSize;
- set
- {
- if (value > 0 && _viewportSize != value)
- {
- _viewportSize = value;
- OnPropertyChanged(nameof(ViewportSize));
- TriggerPreload();
- }
- }
- }
-
- ///
- /// 是否正在加载数据
- ///
- public bool IsLoading => _isLoading;
-
- ///
- /// 缓存命中率
- ///
- public double CacheHitRatio { get; private set; }
-
- ///
- /// 是否为只读集合
- ///
- public bool IsReadOnly => false;
-
- #endregion
-
- #region 构造函数
-
- ///
- /// 初始化虚拟化集合
- ///
- /// 数据提供器
- public VirtualizedObservableCollection(IVirtualDataProvider dataProvider)
- {
- _dataProvider = dataProvider ?? throw new ArgumentNullException(nameof(dataProvider));
- _performanceMonitor = DataBindingPerformanceMonitor.Instance;
-
- // 订阅数据提供器事件
- if (dataProvider is INotifyPropertyChanged notifyProvider)
- {
- notifyProvider.PropertyChanged += DataProvider_PropertyChanged;
- }
-
- // 初始化总数量
- InitializeTotalCountAsync();
-
- LogManager.Info($"VirtualizedObservableCollection<{typeof(T).Name}>已初始化");
- }
-
- #endregion
-
- #region 索引器和基本访问
-
- ///
- /// 获取或设置指定索引处的元素
- ///
- /// 元素索引
- /// 指定位置的元素
- public T this[int index]
- {
- get
- {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index));
-
- return GetItemAsync(index).Result;
- }
- set
- {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index));
-
- _ = SetItemAsync(index, value);
- }
- }
-
- ///
- /// 异步获取指定索引的项目
- ///
- /// 项目索引
- /// 项目或null
- public async Task GetItemAsync(int index)
- {
- if (index < 0 || index >= Count)
- return default(T);
-
- using (_performanceMonitor.BeginCollectionUpdate(typeof(VirtualizedObservableCollection), "GetItem", 1))
- {
- // 检查缓存
- lock (_cacheLock)
- {
- if (_itemCache.TryGetValue(index, out var cachedItem))
- {
- _cacheTimestamps[index] = DateTime.UtcNow;
- UpdateCacheHitRatio(true);
- return cachedItem;
- }
- }
-
- UpdateCacheHitRatio(false);
-
- // 异步加载项目
- var item = await LoadItemAsync(index);
-
- // 缓存项目
- lock (_cacheLock)
- {
- _itemCache[index] = item;
- _cacheTimestamps[index] = DateTime.UtcNow;
-
- // 清理过期缓存
- if (_itemCache.Count > _cacheSize)
- {
- CleanupCache();
- }
- }
-
- // 触发预加载
- TriggerPreload(index);
-
- return item;
- }
- }
-
- ///
- /// 异步设置指定索引的项目
- ///
- /// 项目索引
- /// 新项目
- public async Task SetItemAsync(int index, T item)
- {
- if (index < 0 || index >= Count)
- return;
-
- using (_performanceMonitor.BeginCollectionUpdate(typeof(VirtualizedObservableCollection), "SetItem", 1))
- {
- // 更新数据提供器
- await _dataProvider.SetItemAsync(index, item);
-
- // 更新缓存
- lock (_cacheLock)
- {
- _itemCache[index] = item;
- _cacheTimestamps[index] = DateTime.UtcNow;
- }
-
- // 触发变更通知
- OnCollectionChanged(new NotifyCollectionChangedEventArgs(
- NotifyCollectionChangedAction.Replace, item, default(T), index));
- }
- }
-
- #endregion
-
- #region 数据加载和缓存管理
-
- ///
- /// 异步加载单个项目
- ///
- /// 项目索引
- /// 加载的项目
- private async Task LoadItemAsync(int index)
- {
- try
- {
- lock (_loadingLock)
- {
- _isLoading = true;
- }
- OnPropertyChanged(nameof(IsLoading));
-
- return await _dataProvider.GetItemAsync(index);
- }
- catch (Exception ex)
- {
- LogManager.Error($"加载项目失败 [索引: {index}]: {ex.Message}");
- return default(T);
- }
- finally
- {
- lock (_loadingLock)
- {
- _isLoading = false;
- }
- OnPropertyChanged(nameof(IsLoading));
- }
- }
-
- ///
- /// 异步批量加载项目
- ///
- /// 起始索引
- /// 加载数量
- /// 加载的项目列表
- private async Task> LoadRangeAsync(int startIndex, int count)
- {
- try
- {
- lock (_loadingLock)
- {
- _isLoading = true;
- }
- OnPropertyChanged(nameof(IsLoading));
-
- var endIndex = Math.Min(startIndex + count, Count);
- var actualCount = endIndex - startIndex;
-
- if (actualCount <= 0)
- return Enumerable.Empty();
-
- return await _dataProvider.GetRangeAsync(startIndex, actualCount);
- }
- catch (Exception ex)
- {
- LogManager.Error($"批量加载项目失败 [范围: {startIndex}-{startIndex + count}]: {ex.Message}");
- return Enumerable.Empty();
- }
- finally
- {
- lock (_loadingLock)
- {
- _isLoading = false;
- }
- OnPropertyChanged(nameof(IsLoading));
- }
- }
-
- ///
- /// 触发智能预加载
- ///
- /// 最近访问的索引
- private void TriggerPreload(int? accessedIndex = null)
- {
- if (_preloadDistance <= 0)
- return;
-
- Task.Run(async () =>
- {
- try
- {
- // 确定预加载范围
- var centerIndex = accessedIndex ?? (_viewportStart + _viewportSize / 2);
- var preloadStart = Math.Max(0, centerIndex - _preloadDistance);
- var preloadEnd = Math.Min(Count - 1, centerIndex + _preloadDistance);
-
- // 找出需要预加载的索引
- var indexesToPreload = new List();
- lock (_cacheLock)
- {
- for (int i = preloadStart; i <= preloadEnd; i++)
- {
- if (!_itemCache.ContainsKey(i))
- {
- indexesToPreload.Add(i);
- }
- }
- }
-
- if (indexesToPreload.Count == 0)
- return;
-
- // 按页面分组预加载
- var pages = indexesToPreload.GroupBy(i => i / _pageSize);
- foreach (var page in pages)
- {
- var pageStart = page.Key * _pageSize;
- var pageItems = await LoadRangeAsync(pageStart, _pageSize);
-
- // 缓存加载的项目
- lock (_cacheLock)
- {
- var itemArray = pageItems.ToArray();
- for (int i = 0; i < itemArray.Length; i++)
- {
- var index = pageStart + i;
- if (index < Count && !_itemCache.ContainsKey(index))
- {
- _itemCache[index] = itemArray[i];
- _cacheTimestamps[index] = DateTime.UtcNow;
- }
- }
- }
- }
-
- LogManager.Debug($"预加载完成: {indexesToPreload.Count}个项目");
- }
- catch (Exception ex)
- {
- LogManager.Error($"预加载失败: {ex.Message}");
- }
- });
- }
-
- ///
- /// 清理过期缓存
- ///
- private void CleanupCache()
- {
- lock (_cacheLock)
- {
- if (_itemCache.Count <= _cacheSize)
- return;
-
- // 按访问时间排序,移除最久未访问的项目
- var itemsToRemove = _cacheTimestamps
- .OrderBy(kvp => kvp.Value)
- .Take(_itemCache.Count - _cacheSize)
- .Select(kvp => kvp.Key)
- .ToList();
-
- foreach (var index in itemsToRemove)
- {
- _itemCache.Remove(index);
- _cacheTimestamps.Remove(index);
- }
-
- LogManager.Debug($"缓存清理完成: 移除{itemsToRemove.Count}个项目");
- }
- }
-
- ///
- /// 清空所有缓存
- ///
- private void InvalidateCache()
- {
- lock (_cacheLock)
- {
- _itemCache.Clear();
- _cacheTimestamps.Clear();
- CacheHitRatio = 0;
- }
-
- LogManager.Debug("缓存已清空");
- }
-
- ///
- /// 更新缓存命中率
- ///
- /// 是否命中缓存
- private void UpdateCacheHitRatio(bool isHit)
- {
- // 使用简单的移动平均计算命中率
- const double alpha = 0.1; // 平滑因子
- var hitValue = isHit ? 1.0 : 0.0;
- CacheHitRatio = CacheHitRatio * (1 - alpha) + hitValue * alpha;
- }
-
- #endregion
-
- #region 集合操作实现
-
- ///
- /// 添加项目到集合末尾
- ///
- /// 要添加的项目
- public void Add(T item)
- {
- InsertAsync(Count, item).Wait();
- }
-
- ///
- /// 异步添加项目
- ///
- /// 要添加的项目
- public async Task AddAsync(T item)
- {
- await InsertAsync(Count, item);
- }
-
- ///
- /// 在指定位置插入项目
- ///
- /// 插入位置
- /// 要插入的项目
- public void Insert(int index, T item)
- {
- InsertAsync(index, item).Wait();
- }
-
- ///
- /// 异步在指定位置插入项目
- ///
- /// 插入位置
- /// 要插入的项目
- public async Task InsertAsync(int index, T item)
- {
- if (index < 0 || index > Count)
- throw new ArgumentOutOfRangeException(nameof(index));
-
- using (_performanceMonitor.BeginCollectionUpdate(typeof(VirtualizedObservableCollection), "Insert", 1))
- {
- // 在数据提供器中插入
- await _dataProvider.InsertAsync(index, item);
-
- // 更新总数量
- Count++;
-
- // 调整缓存索引
- lock (_cacheLock)
- {
- var itemsToReindex = _itemCache.Where(kvp => kvp.Key >= index).ToList();
- foreach (var kvp in itemsToReindex)
- {
- _itemCache.Remove(kvp.Key);
- _itemCache[kvp.Key + 1] = kvp.Value;
-
- if (_cacheTimestamps.TryGetValue(kvp.Key, out var timestamp))
- {
- _cacheTimestamps.Remove(kvp.Key);
- _cacheTimestamps[kvp.Key + 1] = timestamp;
- }
- }
-
- // 缓存新插入的项目
- _itemCache[index] = item;
- _cacheTimestamps[index] = DateTime.UtcNow;
- }
-
- // 触发变更通知
- OnCollectionChanged(new NotifyCollectionChangedEventArgs(
- NotifyCollectionChangedAction.Add, item, index));
- }
- }
-
- ///
- /// 移除指定项目
- ///
- /// 要移除的项目
- /// 是否成功移除
- public bool Remove(T item)
- {
- var index = IndexOf(item);
- if (index >= 0)
- {
- RemoveAt(index);
- return true;
- }
- return false;
- }
-
- ///
- /// 移除指定位置的项目
- ///
- /// 要移除的项目位置
- public void RemoveAt(int index)
- {
- RemoveAtAsync(index).Wait();
- }
-
- ///
- /// 异步移除指定位置的项目
- ///
- /// 要移除的项目位置
- public async Task RemoveAtAsync(int index)
- {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index));
-
- using (_performanceMonitor.BeginCollectionUpdate(typeof(VirtualizedObservableCollection), "RemoveAt", 1))
- {
- // 获取要移除的项目
- var removedItem = await GetItemAsync(index);
-
- // 从数据提供器中移除
- await _dataProvider.RemoveAtAsync(index);
-
- // 更新总数量
- Count--;
-
- // 调整缓存索引
- lock (_cacheLock)
- {
- _itemCache.Remove(index);
- _cacheTimestamps.Remove(index);
-
- var itemsToReindex = _itemCache.Where(kvp => kvp.Key > index).ToList();
- foreach (var kvp in itemsToReindex)
- {
- _itemCache.Remove(kvp.Key);
- _itemCache[kvp.Key - 1] = kvp.Value;
-
- if (_cacheTimestamps.TryGetValue(kvp.Key, out var timestamp))
- {
- _cacheTimestamps.Remove(kvp.Key);
- _cacheTimestamps[kvp.Key - 1] = timestamp;
- }
- }
- }
-
- // 触发变更通知
- OnCollectionChanged(new NotifyCollectionChangedEventArgs(
- NotifyCollectionChangedAction.Remove, removedItem, index));
- }
- }
-
- ///
- /// 清空集合
- ///
- public void Clear()
- {
- ClearAsync().Wait();
- }
-
- ///
- /// 异步清空集合
- ///
- public async Task ClearAsync()
- {
- using (_performanceMonitor.BeginCollectionUpdate(typeof(VirtualizedObservableCollection), "Clear", Count))
- {
- // 清空数据提供器
- await _dataProvider.ClearAsync();
-
- // 更新状态
- Count = 0;
- InvalidateCache();
-
- // 触发变更通知
- OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
- }
- }
-
- ///
- /// 检查集合是否包含指定项目
- ///
- /// 要检查的项目
- /// 是否包含
- public bool Contains(T item)
- {
- return IndexOf(item) >= 0;
- }
-
- ///
- /// 查找项目的索引
- ///
- /// 要查找的项目
- /// 项目索引,如果不存在返回-1
- public int IndexOf(T item)
- {
- // 首先在缓存中查找
- lock (_cacheLock)
- {
- foreach (var kvp in _itemCache)
- {
- if (EqualityComparer.Default.Equals(kvp.Value, item))
- {
- return kvp.Key;
- }
- }
- }
-
- // 如果缓存中没有,使用数据提供器查找
- return _dataProvider.IndexOfAsync(item).Result;
- }
-
- ///
- /// 复制集合项目到数组
- ///
- /// 目标数组
- /// 起始索引
- public void CopyTo(T[] array, int arrayIndex)
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array));
-
- if (arrayIndex < 0 || arrayIndex + Count > array.Length)
- throw new ArgumentOutOfRangeException(nameof(arrayIndex));
-
- for (int i = 0; i < Count; i++)
- {
- array[arrayIndex + i] = this[i];
- }
- }
-
- #endregion
-
- #region 枚举器实现
-
- ///
- /// 获取枚举器
- ///
- /// 枚举器
- public IEnumerator GetEnumerator()
- {
- return new VirtualizedEnumerator(this);
- }
-
- ///
- /// 获取非泛型枚举器
- ///
- /// 枚举器
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
-
- ///
- /// 虚拟化枚举器 - 按需加载数据
- ///
- private class VirtualizedEnumerator : IEnumerator
- {
- private readonly VirtualizedObservableCollection _collection;
- private int _currentIndex = -1;
-
- public VirtualizedEnumerator(VirtualizedObservableCollection collection)
- {
- _collection = collection;
- }
-
- public T Current { get; private set; }
-
- object IEnumerator.Current => Current;
-
- public bool MoveNext()
- {
- if (_currentIndex + 1 < _collection.Count)
- {
- _currentIndex++;
- Current = _collection.GetItemAsync(_currentIndex).Result;
- return true;
- }
- return false;
- }
-
- public void Reset()
- {
- _currentIndex = -1;
- Current = default(T);
- }
-
- public void Dispose()
- {
- Current = default(T);
- }
- }
-
- #endregion
-
- #region 事件处理
-
- ///
- /// 初始化总数量
- ///
- private async void InitializeTotalCountAsync()
- {
- try
- {
- var totalCount = await _dataProvider.GetTotalCountAsync();
- Count = totalCount;
- LogManager.Info($"虚拟化集合初始化完成,总数量: {totalCount}");
- }
- catch (Exception ex)
- {
- LogManager.Error($"获取总数量失败: {ex.Message}");
- Count = 0;
- }
- }
-
- ///
- /// 数据提供器属性变更处理
- ///
- private async void DataProvider_PropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == "TotalCount")
- {
- try
- {
- var newCount = await _dataProvider.GetTotalCountAsync();
- if (newCount != Count)
- {
- Count = newCount;
- InvalidateCache();
- OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
- }
- }
- catch (Exception ex)
- {
- LogManager.Error($"更新总数量失败: {ex.Message}");
- }
- }
- }
-
- ///
- /// 触发集合变更事件
- ///
- /// 事件参数
- protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
- {
- CollectionChanged?.Invoke(this, e);
- }
-
- ///
- /// 触发属性变更事件
- ///
- /// 属性名称
- protected virtual void OnPropertyChanged(string propertyName)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
-
- #endregion
-
- #region 诊断和统计
-
- ///
- /// 获取虚拟化统计信息
- ///
- /// 统计信息
- public VirtualizationStatistics GetStatistics()
- {
- lock (_cacheLock)
- {
- return new VirtualizationStatistics
- {
- TotalCount = Count,
- CachedItemsCount = _itemCache.Count,
- CacheHitRatio = CacheHitRatio,
- PageSize = PageSize,
- CacheSize = CacheSize,
- PreloadDistance = PreloadDistance,
- ViewportStart = ViewportStart,
- ViewportSize = ViewportSize,
- IsLoading = IsLoading
- };
- }
- }
-
- ///
- /// 生成诊断报告
- ///
- /// 诊断报告
- public string GenerateDiagnosticReport()
- {
- var stats = GetStatistics();
- var report = new System.Text.StringBuilder();
-
- report.AppendLine("=== 虚拟化集合诊断报告 ===");
- report.AppendLine($"集合类型: {typeof(T).Name}");
- report.AppendLine($"总项目数: {stats.TotalCount:N0}");
- report.AppendLine($"缓存项目数: {stats.CachedItemsCount:N0}");
- report.AppendLine($"缓存命中率: {stats.CacheHitRatio:P2}");
- report.AppendLine($"页面大小: {stats.PageSize}");
- report.AppendLine($"缓存大小: {stats.CacheSize}");
- report.AppendLine($"预加载距离: {stats.PreloadDistance}");
- report.AppendLine($"视口位置: {stats.ViewportStart}-{stats.ViewportStart + stats.ViewportSize}");
- report.AppendLine($"加载状态: {(stats.IsLoading ? "加载中" : "空闲")}");
-
- var memoryEfficiency = stats.TotalCount > 0 ? (double)stats.CachedItemsCount / stats.TotalCount : 0;
- report.AppendLine($"内存效率: {memoryEfficiency:P2} ({stats.CachedItemsCount}/{stats.TotalCount})");
-
- return report.ToString();
- }
-
- #endregion
- }
-
- #region 虚拟数据提供器接口
-
- ///
- /// 虚拟数据提供器接口 - 为虚拟化集合提供数据访问抽象
- ///
- /// 数据类型
- public interface IVirtualDataProvider
- {
- ///
- /// 获取总项目数量
- ///
- /// 总数量
- Task GetTotalCountAsync();
-
- ///
- /// 获取指定索引的项目
- ///
- /// 索引
- /// 项目
- Task GetItemAsync(int index);
-
- ///
- /// 获取指定范围的项目
- ///
- /// 起始索引
- /// 数量
- /// 项目列表
- Task> GetRangeAsync(int startIndex, int count);
-
- ///
- /// 设置指定索引的项目
- ///
- /// 索引
- /// 新项目
- Task SetItemAsync(int index, T item);
-
- ///
- /// 在指定位置插入项目
- ///
- /// 插入位置
- /// 要插入的项目
- Task InsertAsync(int index, T item);
-
- ///
- /// 移除指定位置的项目
- ///
- /// 位置
- Task RemoveAtAsync(int index);
-
- ///
- /// 清空所有项目
- ///
- Task ClearAsync();
-
- ///
- /// 查找项目索引
- ///
- /// 要查找的项目
- /// 索引,如果不存在返回-1
- Task IndexOfAsync(T item);
- }
-
- ///
- /// 虚拟化统计信息
- ///
- public class VirtualizationStatistics
- {
- public int TotalCount { get; set; }
- public int CachedItemsCount { get; set; }
- public double CacheHitRatio { get; set; }
- public int PageSize { get; set; }
- public int CacheSize { get; set; }
- public int PreloadDistance { get; set; }
- public int ViewportStart { get; set; }
- public int ViewportSize { get; set; }
- public bool IsLoading { get; set; }
- }
-
- #endregion
-}
\ No newline at end of file
diff --git a/src/UI/WPF/Services/CrossViewModelSynchronizer.cs b/src/UI/WPF/Services/CrossViewModelSynchronizer.cs
deleted file mode 100644
index 4ea3b0a..0000000
--- a/src/UI/WPF/Services/CrossViewModelSynchronizer.cs
+++ /dev/null
@@ -1,1029 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Threading;
-using NavisworksTransport.UI.WPF.ViewModels;
-using NavisworksTransport.Utils;
-
-namespace NavisworksTransport.UI.WPF.Services
-{
- ///
- /// 跨ViewModel数据同步优化器 - 确保数据一致性和高效的同步性能
- /// 支持发布-订阅模式、依赖追踪和智能批量同步
- ///
- public class CrossViewModelSynchronizer : IDisposable
- {
- #region 字段和属性
-
- private static CrossViewModelSynchronizer _instance;
- private static readonly object _instanceLock = new object();
-
- // 订阅管理
- private readonly ConcurrentDictionary> _subscriptions;
- private readonly ConcurrentDictionary _viewModelRegistry;
-
- // 依赖追踪
- private readonly ConcurrentDictionary> _propertyDependencies;
- private readonly ConcurrentDictionary> _viewModelDependencies;
-
- // 同步队列和批量处理
- private readonly ConcurrentQueue _synchronizationQueue;
- private readonly Timer _batchProcessingTimer;
- private readonly object _processingLock = new object();
- private volatile bool _isProcessing = false;
- private volatile bool _isDisposed = false;
-
- // 性能监控
- private readonly DataBindingPerformanceMonitor _performanceMonitor;
-
- // 配置选项
- private TimeSpan _batchProcessingInterval = TimeSpan.FromMilliseconds(50);
- private int _maxBatchSize = 100;
- private bool _enableSmartBatching = true;
- private bool _enableDependencyTracking = true;
-
- ///
- /// 获取跨ViewModel同步器的单例实例
- ///
- public static CrossViewModelSynchronizer Instance
- {
- get
- {
- if (_instance == null)
- {
- lock (_instanceLock)
- {
- if (_instance == null)
- {
- _instance = new CrossViewModelSynchronizer();
- }
- }
- }
- return _instance;
- }
- }
-
- ///
- /// 批量处理间隔
- ///
- public TimeSpan BatchProcessingInterval
- {
- get => _batchProcessingInterval;
- set
- {
- _batchProcessingInterval = value;
- _batchProcessingTimer?.Change(value, value);
- }
- }
-
- ///
- /// 最大批量处理大小
- ///
- public int MaxBatchSize
- {
- get => _maxBatchSize;
- set => _maxBatchSize = Math.Max(1, value);
- }
-
- ///
- /// 是否启用智能批量处理
- ///
- public bool EnableSmartBatching
- {
- get => _enableSmartBatching;
- set => _enableSmartBatching = value;
- }
-
- ///
- /// 是否启用依赖追踪
- ///
- public bool EnableDependencyTracking
- {
- get => _enableDependencyTracking;
- set => _enableDependencyTracking = value;
- }
-
- ///
- /// 当前注册的ViewModel数量
- ///
- public int RegisteredViewModelsCount => _viewModelRegistry.Count;
-
- ///
- /// 当前订阅总数
- ///
- public int TotalSubscriptionsCount => _subscriptions.Values.Sum(bag => bag.Count);
-
- ///
- /// 等待同步的事件数量
- ///
- public int PendingSynchronizationCount => _synchronizationQueue.Count;
-
- #endregion
-
- #region 构造函数
-
- private CrossViewModelSynchronizer()
- {
- _subscriptions = new ConcurrentDictionary>();
- _viewModelRegistry = new ConcurrentDictionary();
- _propertyDependencies = new ConcurrentDictionary>();
- _viewModelDependencies = new ConcurrentDictionary>();
- _synchronizationQueue = new ConcurrentQueue();
- _performanceMonitor = DataBindingPerformanceMonitor.Instance;
-
- // 初始化批量处理定时器
- _batchProcessingTimer = new Timer(ProcessSynchronizationBatch, null, _batchProcessingInterval, _batchProcessingInterval);
-
- LogManager.Info("跨ViewModel数据同步器已初始化");
- }
-
- #endregion
-
- #region ViewModel注册和管理
-
- ///
- /// 注册ViewModel以启用同步功能
- ///
- /// 要注册的ViewModel
- /// 同步选项
- public void RegisterViewModel(ViewModelBase viewModel, ViewModelSyncOptions options = null)
- {
- if (_isDisposed || viewModel == null)
- return;
-
- options = options ?? ViewModelSyncOptions.Default;
-
- var metadata = new ViewModelMetadata
- {
- ViewModel = viewModel,
- Options = options,
- RegistrationTime = DateTime.UtcNow,
- LastSyncTime = DateTime.UtcNow,
- SyncEventCount = 0
- };
-
- _viewModelRegistry.TryAdd(viewModel, metadata);
-
- // 订阅PropertyChanged事件
- viewModel.PropertyChanged += ViewModel_PropertyChanged;
-
- // 初始化依赖追踪
- if (_enableDependencyTracking && options.TrackedProperties?.Length > 0)
- {
- InitializeDependencyTracking(viewModel, options.TrackedProperties);
- }
-
- LogManager.Debug($"ViewModel已注册同步: {viewModel.GetType().Name}");
- }
-
- ///
- /// 注销ViewModel
- ///
- /// 要注销的ViewModel
- public void UnregisterViewModel(ViewModelBase viewModel)
- {
- if (_isDisposed || viewModel == null)
- return;
-
- // 移除订阅
- viewModel.PropertyChanged -= ViewModel_PropertyChanged;
-
- // 清理注册信息
- _viewModelRegistry.TryRemove(viewModel, out _);
-
- // 清理相关订阅
- RemoveViewModelSubscriptions(viewModel);
-
- // 清理依赖追踪
- _viewModelDependencies.TryRemove(viewModel, out _);
-
- LogManager.Debug($"ViewModel已注销同步: {viewModel.GetType().Name}");
- }
-
- ///
- /// 初始化依赖追踪
- ///
- /// ViewModel
- /// 需要追踪的属性
- private void InitializeDependencyTracking(ViewModelBase viewModel, string[] trackedProperties)
- {
- var dependencies = new HashSet(trackedProperties);
- _viewModelDependencies.TryAdd(viewModel, dependencies);
-
- foreach (var property in trackedProperties)
- {
- var key = CreatePropertyKey(viewModel, property);
- _propertyDependencies.GetOrAdd(key, _ => new HashSet());
- }
- }
-
- #endregion
-
- #region 订阅管理
-
- ///
- /// 订阅属性变更事件
- ///
- /// 源ViewModel
- /// 源属性名
- /// 目标ViewModel
- /// 目标属性名
- /// 值转换器(可选)
- /// 订阅选项
- /// 订阅ID
- public string Subscribe(ViewModelBase sourceViewModel, string sourceProperty,
- ViewModelBase targetViewModel, string targetProperty,
- Func