阶段三:删除未使用的WPF Services

删除的文件:
- src/UI/WPF/Services/DataBindingBestPractices.cs (0次外部引用)
- src/UI/WPF/Services/CrossViewModelSynchronizer.cs (仅被BestPractices使用)
- src/UI/WPF/Collections/VirtualizedObservableCollection.cs (仅被BestPractices引用)

更新:
- 从NavisworksTransportPlugin.csproj中移除引用

编译验证通过

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
tian 2025-09-30 22:20:29 +08:00
parent b048235657
commit 52bb3da0eb
5 changed files with 2 additions and 2979 deletions

View File

@ -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": [

View File

@ -227,15 +227,12 @@
<!-- UI - WPF Collections -->
<Compile Include="src\UI\WPF\Collections\ThreadSafeObservableCollection.cs" />
<Compile Include="src\UI\WPF\Collections\VirtualizedObservableCollection.cs" />
<!-- UI - WPF Interfaces -->
<Compile Include="src\UI\WPF\Interfaces\IPropertyChangeNotifier.cs" />
<!-- UI - WPF Services -->
<Compile Include="src\UI\WPF\Services\BindingExpressionOptimizer.cs" />
<Compile Include="src\UI\WPF\Services\CrossViewModelSynchronizer.cs" />
<Compile Include="src\UI\WPF\Services\DataBindingBestPractices.cs" />
<Compile Include="src\UI\WPF\Services\DataBindingPerformanceMonitor.cs" />
<Compile Include="src\UI\WPF\Services\SmartDataBindingOptimizer.cs" />

View File

@ -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
{
/// <summary>
/// 虚拟化的可观察集合 - 为大数据集合提供高性能的WPF绑定支持
/// 只在内存中保存可见项目,按需加载数据,支持智能预加载和缓存
/// </summary>
/// <typeparam name="T">集合元素类型</typeparam>
public class VirtualizedObservableCollection<T> : IList<T>, INotifyCollectionChanged, INotifyPropertyChanged
{
#region
// 数据提供器
private readonly IVirtualDataProvider<T> _dataProvider;
private readonly DataBindingPerformanceMonitor _performanceMonitor;
// 虚拟化设置
private int _pageSize = 100;
private int _cacheSize = 500;
private int _preloadDistance = 50;
// 缓存管理
private readonly Dictionary<int, T> _itemCache = new Dictionary<int, T>();
private readonly Dictionary<int, DateTime> _cacheTimestamps = new Dictionary<int, DateTime>();
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;
/// <summary>
/// 集合变更事件
/// </summary>
public event NotifyCollectionChangedEventHandler CollectionChanged;
/// <summary>
/// 属性变更事件
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 总项目数量
/// </summary>
public int Count
{
get => _totalCount;
private set
{
if (_totalCount != value)
{
_totalCount = value;
OnPropertyChanged(nameof(Count));
}
}
}
/// <summary>
/// 页面大小 - 每次从数据提供器加载的项目数量
/// </summary>
public int PageSize
{
get => _pageSize;
set
{
if (value > 0 && _pageSize != value)
{
_pageSize = value;
OnPropertyChanged(nameof(PageSize));
InvalidateCache();
}
}
}
/// <summary>
/// 缓存大小 - 内存中保存的最大项目数量
/// </summary>
public int CacheSize
{
get => _cacheSize;
set
{
if (value > 0 && _cacheSize != value)
{
_cacheSize = value;
OnPropertyChanged(nameof(CacheSize));
CleanupCache();
}
}
}
/// <summary>
/// 预加载距离 - 距离视口边缘多远开始预加载
/// </summary>
public int PreloadDistance
{
get => _preloadDistance;
set
{
if (value >= 0 && _preloadDistance != value)
{
_preloadDistance = value;
OnPropertyChanged(nameof(PreloadDistance));
}
}
}
/// <summary>
/// 当前视口起始位置
/// </summary>
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();
}
}
}
/// <summary>
/// 视口大小 - 可见区域的项目数量
/// </summary>
public int ViewportSize
{
get => _viewportSize;
set
{
if (value > 0 && _viewportSize != value)
{
_viewportSize = value;
OnPropertyChanged(nameof(ViewportSize));
TriggerPreload();
}
}
}
/// <summary>
/// 是否正在加载数据
/// </summary>
public bool IsLoading => _isLoading;
/// <summary>
/// 缓存命中率
/// </summary>
public double CacheHitRatio { get; private set; }
/// <summary>
/// 是否为只读集合
/// </summary>
public bool IsReadOnly => false;
#endregion
#region
/// <summary>
/// 初始化虚拟化集合
/// </summary>
/// <param name="dataProvider">数据提供器</param>
public VirtualizedObservableCollection(IVirtualDataProvider<T> 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 访
/// <summary>
/// 获取或设置指定索引处的元素
/// </summary>
/// <param name="index">元素索引</param>
/// <returns>指定位置的元素</returns>
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);
}
}
/// <summary>
/// 异步获取指定索引的项目
/// </summary>
/// <param name="index">项目索引</param>
/// <returns>项目或null</returns>
public async Task<T> GetItemAsync(int index)
{
if (index < 0 || index >= Count)
return default(T);
using (_performanceMonitor.BeginCollectionUpdate(typeof(VirtualizedObservableCollection<T>), "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;
}
}
/// <summary>
/// 异步设置指定索引的项目
/// </summary>
/// <param name="index">项目索引</param>
/// <param name="item">新项目</param>
public async Task SetItemAsync(int index, T item)
{
if (index < 0 || index >= Count)
return;
using (_performanceMonitor.BeginCollectionUpdate(typeof(VirtualizedObservableCollection<T>), "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
/// <summary>
/// 异步加载单个项目
/// </summary>
/// <param name="index">项目索引</param>
/// <returns>加载的项目</returns>
private async Task<T> 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));
}
}
/// <summary>
/// 异步批量加载项目
/// </summary>
/// <param name="startIndex">起始索引</param>
/// <param name="count">加载数量</param>
/// <returns>加载的项目列表</returns>
private async Task<IEnumerable<T>> 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<T>();
return await _dataProvider.GetRangeAsync(startIndex, actualCount);
}
catch (Exception ex)
{
LogManager.Error($"批量加载项目失败 [范围: {startIndex}-{startIndex + count}]: {ex.Message}");
return Enumerable.Empty<T>();
}
finally
{
lock (_loadingLock)
{
_isLoading = false;
}
OnPropertyChanged(nameof(IsLoading));
}
}
/// <summary>
/// 触发智能预加载
/// </summary>
/// <param name="accessedIndex">最近访问的索引</param>
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<int>();
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}");
}
});
}
/// <summary>
/// 清理过期缓存
/// </summary>
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}个项目");
}
}
/// <summary>
/// 清空所有缓存
/// </summary>
private void InvalidateCache()
{
lock (_cacheLock)
{
_itemCache.Clear();
_cacheTimestamps.Clear();
CacheHitRatio = 0;
}
LogManager.Debug("缓存已清空");
}
/// <summary>
/// 更新缓存命中率
/// </summary>
/// <param name="isHit">是否命中缓存</param>
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
/// <summary>
/// 添加项目到集合末尾
/// </summary>
/// <param name="item">要添加的项目</param>
public void Add(T item)
{
InsertAsync(Count, item).Wait();
}
/// <summary>
/// 异步添加项目
/// </summary>
/// <param name="item">要添加的项目</param>
public async Task AddAsync(T item)
{
await InsertAsync(Count, item);
}
/// <summary>
/// 在指定位置插入项目
/// </summary>
/// <param name="index">插入位置</param>
/// <param name="item">要插入的项目</param>
public void Insert(int index, T item)
{
InsertAsync(index, item).Wait();
}
/// <summary>
/// 异步在指定位置插入项目
/// </summary>
/// <param name="index">插入位置</param>
/// <param name="item">要插入的项目</param>
public async Task InsertAsync(int index, T item)
{
if (index < 0 || index > Count)
throw new ArgumentOutOfRangeException(nameof(index));
using (_performanceMonitor.BeginCollectionUpdate(typeof(VirtualizedObservableCollection<T>), "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));
}
}
/// <summary>
/// 移除指定项目
/// </summary>
/// <param name="item">要移除的项目</param>
/// <returns>是否成功移除</returns>
public bool Remove(T item)
{
var index = IndexOf(item);
if (index >= 0)
{
RemoveAt(index);
return true;
}
return false;
}
/// <summary>
/// 移除指定位置的项目
/// </summary>
/// <param name="index">要移除的项目位置</param>
public void RemoveAt(int index)
{
RemoveAtAsync(index).Wait();
}
/// <summary>
/// 异步移除指定位置的项目
/// </summary>
/// <param name="index">要移除的项目位置</param>
public async Task RemoveAtAsync(int index)
{
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException(nameof(index));
using (_performanceMonitor.BeginCollectionUpdate(typeof(VirtualizedObservableCollection<T>), "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));
}
}
/// <summary>
/// 清空集合
/// </summary>
public void Clear()
{
ClearAsync().Wait();
}
/// <summary>
/// 异步清空集合
/// </summary>
public async Task ClearAsync()
{
using (_performanceMonitor.BeginCollectionUpdate(typeof(VirtualizedObservableCollection<T>), "Clear", Count))
{
// 清空数据提供器
await _dataProvider.ClearAsync();
// 更新状态
Count = 0;
InvalidateCache();
// 触发变更通知
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
/// <summary>
/// 检查集合是否包含指定项目
/// </summary>
/// <param name="item">要检查的项目</param>
/// <returns>是否包含</returns>
public bool Contains(T item)
{
return IndexOf(item) >= 0;
}
/// <summary>
/// 查找项目的索引
/// </summary>
/// <param name="item">要查找的项目</param>
/// <returns>项目索引,如果不存在返回-1</returns>
public int IndexOf(T item)
{
// 首先在缓存中查找
lock (_cacheLock)
{
foreach (var kvp in _itemCache)
{
if (EqualityComparer<T>.Default.Equals(kvp.Value, item))
{
return kvp.Key;
}
}
}
// 如果缓存中没有,使用数据提供器查找
return _dataProvider.IndexOfAsync(item).Result;
}
/// <summary>
/// 复制集合项目到数组
/// </summary>
/// <param name="array">目标数组</param>
/// <param name="arrayIndex">起始索引</param>
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
/// <summary>
/// 获取枚举器
/// </summary>
/// <returns>枚举器</returns>
public IEnumerator<T> GetEnumerator()
{
return new VirtualizedEnumerator(this);
}
/// <summary>
/// 获取非泛型枚举器
/// </summary>
/// <returns>枚举器</returns>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// 虚拟化枚举器 - 按需加载数据
/// </summary>
private class VirtualizedEnumerator : IEnumerator<T>
{
private readonly VirtualizedObservableCollection<T> _collection;
private int _currentIndex = -1;
public VirtualizedEnumerator(VirtualizedObservableCollection<T> 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
/// <summary>
/// 初始化总数量
/// </summary>
private async void InitializeTotalCountAsync()
{
try
{
var totalCount = await _dataProvider.GetTotalCountAsync();
Count = totalCount;
LogManager.Info($"虚拟化集合初始化完成,总数量: {totalCount}");
}
catch (Exception ex)
{
LogManager.Error($"获取总数量失败: {ex.Message}");
Count = 0;
}
}
/// <summary>
/// 数据提供器属性变更处理
/// </summary>
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}");
}
}
}
/// <summary>
/// 触发集合变更事件
/// </summary>
/// <param name="e">事件参数</param>
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
CollectionChanged?.Invoke(this, e);
}
/// <summary>
/// 触发属性变更事件
/// </summary>
/// <param name="propertyName">属性名称</param>
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
#region
/// <summary>
/// 获取虚拟化统计信息
/// </summary>
/// <returns>统计信息</returns>
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
};
}
}
/// <summary>
/// 生成诊断报告
/// </summary>
/// <returns>诊断报告</returns>
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
/// <summary>
/// 虚拟数据提供器接口 - 为虚拟化集合提供数据访问抽象
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
public interface IVirtualDataProvider<T>
{
/// <summary>
/// 获取总项目数量
/// </summary>
/// <returns>总数量</returns>
Task<int> GetTotalCountAsync();
/// <summary>
/// 获取指定索引的项目
/// </summary>
/// <param name="index">索引</param>
/// <returns>项目</returns>
Task<T> GetItemAsync(int index);
/// <summary>
/// 获取指定范围的项目
/// </summary>
/// <param name="startIndex">起始索引</param>
/// <param name="count">数量</param>
/// <returns>项目列表</returns>
Task<IEnumerable<T>> GetRangeAsync(int startIndex, int count);
/// <summary>
/// 设置指定索引的项目
/// </summary>
/// <param name="index">索引</param>
/// <param name="item">新项目</param>
Task SetItemAsync(int index, T item);
/// <summary>
/// 在指定位置插入项目
/// </summary>
/// <param name="index">插入位置</param>
/// <param name="item">要插入的项目</param>
Task InsertAsync(int index, T item);
/// <summary>
/// 移除指定位置的项目
/// </summary>
/// <param name="index">位置</param>
Task RemoveAtAsync(int index);
/// <summary>
/// 清空所有项目
/// </summary>
Task ClearAsync();
/// <summary>
/// 查找项目索引
/// </summary>
/// <param name="item">要查找的项目</param>
/// <returns>索引,如果不存在返回-1</returns>
Task<int> IndexOfAsync(T item);
}
/// <summary>
/// 虚拟化统计信息
/// </summary>
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
}

File diff suppressed because it is too large Load Diff

View File

@ -1,964 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Data;
using NavisworksTransport.UI.WPF.ViewModels;
using NavisworksTransport.UI.WPF.Collections;
using NavisworksTransport.Utils;
namespace NavisworksTransport.UI.WPF.Services
{
/// <summary>
/// 数据绑定最佳实践指南和验证工具
/// 提供数据绑定性能优化的最佳实践指导和自动化验证
/// </summary>
public static class DataBindingBestPractices
{
#region
/// <summary>
/// 最佳实践规则集合
/// </summary>
public static readonly List<BestPracticeRule> Rules = new List<BestPracticeRule>
{
// ViewModel相关规则
new BestPracticeRule
{
Id = "VM01",
Category = BestPracticeCategory.ViewModel,
Title = "继承ViewModelBase基类",
Description = "所有ViewModel应继承ViewModelBase以获得线程安全和性能优化功能",
Severity = RuleSeverity.Error,
CheckAction = CheckViewModelBaseInheritance
},
new BestPracticeRule
{
Id = "VM02",
Category = BestPracticeCategory.ViewModel,
Title = "使用智能属性设置方法",
Description = "使用SetPropertySmart方法替代传统SetProperty以获得更好的性能",
Severity = RuleSeverity.Warning,
CheckAction = CheckSmartPropertyUsage
},
new BestPracticeRule
{
Id = "VM03",
Category = BestPracticeCategory.ViewModel,
Title = "启用性能监控",
Description = "在开发和测试阶段启用性能监控以识别性能瓶颈",
Severity = RuleSeverity.Information,
CheckAction = CheckPerformanceMonitoring
},
new BestPracticeRule
{
Id = "VM04",
Category = BestPracticeCategory.ViewModel,
Title = "避免频繁属性更新",
Description = "对于频繁更新的属性,使用延迟更新或批量更新机制",
Severity = RuleSeverity.Warning,
CheckAction = CheckFrequentPropertyUpdates
},
// 集合相关规则
new BestPracticeRule
{
Id = "COL01",
Category = BestPracticeCategory.Collections,
Title = "使用线程安全集合",
Description = "在多线程环境中使用ThreadSafeObservableCollection而不是ObservableCollection",
Severity = RuleSeverity.Error,
CheckAction = CheckThreadSafeCollections
},
new BestPracticeRule
{
Id = "COL02",
Category = BestPracticeCategory.Collections,
Title = "大集合使用虚拟化",
Description = "超过1000项的集合应使用VirtualizedObservableCollection",
Severity = RuleSeverity.Warning,
CheckAction = CheckVirtualizationUsage
},
new BestPracticeRule
{
Id = "COL03",
Category = BestPracticeCategory.Collections,
Title = "使用批量操作",
Description = "集合的批量添加/删除应使用AddRange/RemoveRange方法",
Severity = RuleSeverity.Information,
CheckAction = CheckBatchOperations
},
// 绑定相关规则
new BestPracticeRule
{
Id = "BIND01",
Category = BestPracticeCategory.Binding,
Title = "优化绑定表达式",
Description = "复杂的绑定表达式应注册到BindingExpressionOptimizer",
Severity = RuleSeverity.Warning,
CheckAction = CheckBindingOptimization
},
new BestPracticeRule
{
Id = "BIND02",
Category = BestPracticeCategory.Binding,
Title = "避免双向绑定过度使用",
Description = "只在必要时使用双向绑定,优先使用单向绑定",
Severity = RuleSeverity.Information,
CheckAction = CheckTwoWayBindingUsage
},
new BestPracticeRule
{
Id = "BIND03",
Category = BestPracticeCategory.Binding,
Title = "使用绑定缓存",
Description = "重复计算的绑定值应启用缓存机制",
Severity = RuleSeverity.Information,
CheckAction = CheckBindingCaching
},
// 同步相关规则
new BestPracticeRule
{
Id = "SYNC01",
Category = BestPracticeCategory.Synchronization,
Title = "注册跨ViewModel同步",
Description = "需要数据同步的ViewModel应注册到CrossViewModelSynchronizer",
Severity = RuleSeverity.Warning,
CheckAction = CheckCrossViewModelSync
},
new BestPracticeRule
{
Id = "SYNC02",
Category = BestPracticeCategory.Synchronization,
Title = "避免循环依赖",
Description = "检查并避免ViewModel之间的循环依赖关系",
Severity = RuleSeverity.Error,
CheckAction = CheckCircularDependencies
},
// 内存相关规则
new BestPracticeRule
{
Id = "MEM01",
Category = BestPracticeCategory.Memory,
Title = "及时清理事件订阅",
Description = "ViewModel释放时应正确清理事件订阅以避免内存泄漏",
Severity = RuleSeverity.Error,
CheckAction = CheckEventSubscriptionCleanup
},
new BestPracticeRule
{
Id = "MEM02",
Category = BestPracticeCategory.Memory,
Title = "控制缓存大小",
Description = "各种缓存的大小应根据应用需求进行合理配置",
Severity = RuleSeverity.Information,
CheckAction = CheckCacheConfiguration
}
};
#endregion
#region
/// <summary>
/// 检查ViewModel是否继承ViewModelBase
/// </summary>
private static BestPracticeViolation CheckViewModelBaseInheritance(object context)
{
if (context is ViewModelBase)
{
return null; // 合规
}
if (context is INotifyPropertyChanged viewModel)
{
return new BestPracticeViolation
{
RuleId = "VM01",
Message = $"ViewModel {viewModel.GetType().Name} 应继承 ViewModelBase 基类",
Recommendation = "修改类定义public class MyViewModel : ViewModelBase",
Context = context
};
}
return null;
}
/// <summary>
/// 检查是否使用智能属性设置
/// </summary>
private static BestPracticeViolation CheckSmartPropertyUsage(object context)
{
// 这里可以通过反射或代码分析来检查
// 为了简化,返回建议性信息
if (context is ViewModelBase viewModel)
{
return new BestPracticeViolation
{
RuleId = "VM02",
Message = "建议使用 SetPropertySmart 方法以获得更好的性能",
Recommendation = "使用 SetPropertySmart(ref _field, value, PropertyUpdateMode.Delayed)",
Context = context,
Severity = RuleSeverity.Information
};
}
return null;
}
/// <summary>
/// 检查性能监控是否启用
/// </summary>
private static BestPracticeViolation CheckPerformanceMonitoring(object context)
{
var monitor = DataBindingPerformanceMonitor.Instance;
if (!monitor.IsMonitoringEnabled)
{
return new BestPracticeViolation
{
RuleId = "VM03",
Message = "性能监控未启用,建议在开发阶段启用以识别性能问题",
Recommendation = "调用 DataBindingPerformanceMonitor.Instance.IsMonitoringEnabled = true",
Context = context,
Severity = RuleSeverity.Information
};
}
return null;
}
/// <summary>
/// 检查频繁属性更新
/// </summary>
private static BestPracticeViolation CheckFrequentPropertyUpdates(object context)
{
// 通过性能监控数据检查
var monitor = DataBindingPerformanceMonitor.Instance;
var overview = monitor.GetPerformanceOverview();
if (overview.TotalSlowUpdates > overview.TotalPropertyUpdates * 0.1) // 超过10%的慢更新
{
return new BestPracticeViolation
{
RuleId = "VM04",
Message = $"检测到较多的慢属性更新 ({overview.TotalSlowUpdates} / {overview.TotalPropertyUpdates})",
Recommendation = "考虑使用延迟更新或批量更新机制",
Context = context,
Severity = RuleSeverity.Warning
};
}
return null;
}
/// <summary>
/// 检查线程安全集合使用
/// </summary>
private static BestPracticeViolation CheckThreadSafeCollections(object context)
{
if (context is System.Collections.ObjectModel.ObservableCollection<object> collection &&
!(collection is ThreadSafeObservableCollection<object>))
{
return new BestPracticeViolation
{
RuleId = "COL01",
Message = "在多线程环境中应使用 ThreadSafeObservableCollection",
Recommendation = "替换为: new ThreadSafeObservableCollection<T>()",
Context = context,
Severity = RuleSeverity.Error
};
}
return null;
}
/// <summary>
/// 检查虚拟化集合使用
/// </summary>
private static BestPracticeViolation CheckVirtualizationUsage(object context)
{
if (context is System.Collections.ICollection collection && collection.Count > 1000)
{
if (!(collection is VirtualizedObservableCollection<object>))
{
return new BestPracticeViolation
{
RuleId = "COL02",
Message = $"大集合 ({collection.Count} 项) 建议使用虚拟化",
Recommendation = "使用 VirtualizedObservableCollection<T> 以提高性能",
Context = context,
Severity = RuleSeverity.Warning
};
}
}
return null;
}
/// <summary>
/// 检查批量操作使用
/// </summary>
private static BestPracticeViolation CheckBatchOperations(object context)
{
// 这里可以通过方法调用分析来检查
// 为简化,返回建议信息
return new BestPracticeViolation
{
RuleId = "COL03",
Message = "建议使用批量操作方法提高集合操作性能",
Recommendation = "使用 AddRange() / RemoveRange() 而不是循环调用 Add() / Remove()",
Context = context,
Severity = RuleSeverity.Information
};
}
/// <summary>
/// 检查绑定优化
/// </summary>
private static BestPracticeViolation CheckBindingOptimization(object context)
{
var optimizer = BindingExpressionOptimizer.Instance;
var stats = optimizer.GetStatistics();
if (stats.RegisteredBindingsCount == 0)
{
return new BestPracticeViolation
{
RuleId = "BIND01",
Message = "没有注册绑定优化,复杂绑定可能存在性能问题",
Recommendation = "使用 BindingExpressionOptimizer.OptimizeBinding() 注册复杂绑定",
Context = context,
Severity = RuleSeverity.Information
};
}
return null;
}
/// <summary>
/// 检查双向绑定使用
/// </summary>
private static BestPracticeViolation CheckTwoWayBindingUsage(object context)
{
// 静态分析检查,这里返回建议
return new BestPracticeViolation
{
RuleId = "BIND02",
Message = "检查双向绑定的必要性",
Recommendation = "只在必要时使用 Mode=TwoWay优先使用 Mode=OneWay",
Context = context,
Severity = RuleSeverity.Information
};
}
/// <summary>
/// 检查绑定缓存
/// </summary>
private static BestPracticeViolation CheckBindingCaching(object context)
{
var optimizer = BindingExpressionOptimizer.Instance;
if (!optimizer.EnableBindingCaching)
{
return new BestPracticeViolation
{
RuleId = "BIND03",
Message = "绑定缓存未启用",
Recommendation = "启用绑定缓存: BindingExpressionOptimizer.Instance.EnableBindingCaching = true",
Context = context,
Severity = RuleSeverity.Information
};
}
return null;
}
/// <summary>
/// 检查跨ViewModel同步
/// </summary>
private static BestPracticeViolation CheckCrossViewModelSync(object context)
{
var synchronizer = CrossViewModelSynchronizer.Instance;
var stats = synchronizer.GetStatistics();
if (stats.RegisteredViewModelsCount == 0)
{
return new BestPracticeViolation
{
RuleId = "SYNC01",
Message = "没有注册ViewModel同步可能存在数据一致性问题",
Recommendation = "使用 CrossViewModelSynchronizer.RegisterViewModel() 注册需要同步的ViewModel",
Context = context,
Severity = RuleSeverity.Information
};
}
return null;
}
/// <summary>
/// 检查循环依赖
/// </summary>
private static BestPracticeViolation CheckCircularDependencies(object context)
{
if (context is ViewModelBase viewModel)
{
var synchronizer = CrossViewModelSynchronizer.Instance;
// 检查是否存在循环依赖(简化检查)
try
{
// 这里可以实现更复杂的循环依赖检测逻辑
var dependencies = synchronizer.GetPropertyDependencies(viewModel, "*");
if (dependencies.Any())
{
return new BestPracticeViolation
{
RuleId = "SYNC02",
Message = "检测到可能的循环依赖",
Recommendation = "检查ViewModel之间的依赖关系避免循环引用",
Context = context,
Severity = RuleSeverity.Warning
};
}
}
catch
{
// 检查失败,忽略
}
}
return null;
}
/// <summary>
/// 检查事件订阅清理
/// </summary>
private static BestPracticeViolation CheckEventSubscriptionCleanup(object context)
{
if (context is IDisposable)
{
return null; // 实现了IDisposable假设会正确清理
}
if (context is ViewModelBase)
{
return new BestPracticeViolation
{
RuleId = "MEM01",
Message = "ViewModel应实现IDisposable以正确清理资源",
Recommendation = "实现IDisposable接口并在Dispose中清理事件订阅",
Context = context,
Severity = RuleSeverity.Warning
};
}
return null;
}
/// <summary>
/// 检查缓存配置
/// </summary>
private static BestPracticeViolation CheckCacheConfiguration(object context)
{
var monitor = DataBindingPerformanceMonitor.Instance;
var bindingOptimizer = BindingExpressionOptimizer.Instance;
if (bindingOptimizer.MaxCacheSize < 100)
{
return new BestPracticeViolation
{
RuleId = "MEM02",
Message = "绑定缓存大小可能过小",
Recommendation = "考虑增加缓存大小以提高性能",
Context = context,
Severity = RuleSeverity.Information
};
}
return null;
}
#endregion
#region
/// <summary>
/// 验证对象的数据绑定最佳实践合规性
/// </summary>
/// <param name="context">要验证的对象</param>
/// <param name="categories">要检查的规则类别</param>
/// <returns>违规列表</returns>
public static List<BestPracticeViolation> ValidateObject(object context, params BestPracticeCategory[] categories)
{
var violations = new List<BestPracticeViolation>();
if (context == null)
return violations;
var categoriesToCheck = categories?.Length > 0 ? categories : (BestPracticeCategory[])Enum.GetValues(typeof(BestPracticeCategory));
foreach (var rule in Rules)
{
if (System.Linq.Enumerable.Contains(categoriesToCheck, rule.Category))
{
try
{
var violation = rule.CheckAction?.Invoke(context);
if (violation != null)
{
violations.Add(violation);
}
}
catch (Exception ex)
{
LogManager.Error($"规则检查失败 {rule.Id}: {ex.Message}");
}
}
}
return violations;
}
/// <summary>
/// 验证ViewModel的数据绑定最佳实践
/// </summary>
/// <param name="viewModel">要验证的ViewModel</param>
/// <returns>验证报告</returns>
public static BestPracticeReport ValidateViewModel(ViewModelBase viewModel)
{
var violations = ValidateObject(viewModel);
return new BestPracticeReport
{
TargetObject = viewModel,
TargetType = viewModel.GetType(),
ValidationTime = DateTime.UtcNow,
Violations = violations,
OverallScore = CalculateScore(violations)
};
}
/// <summary>
/// 验证整个应用的数据绑定最佳实践
/// </summary>
/// <param name="viewModels">要验证的ViewModel集合</param>
/// <returns>应用验证报告</returns>
public static ApplicationBestPracticeReport ValidateApplication(IEnumerable<ViewModelBase> viewModels)
{
var reports = new List<BestPracticeReport>();
var allViolations = new List<BestPracticeViolation>();
foreach (var viewModel in viewModels)
{
var report = ValidateViewModel(viewModel);
reports.Add(report);
allViolations.AddRange(report.Violations);
}
// 添加系统级检查
var systemViolations = ValidateSystemConfiguration();
allViolations.AddRange(systemViolations);
return new ApplicationBestPracticeReport
{
ValidationTime = DateTime.UtcNow,
ViewModelReports = reports,
SystemViolations = systemViolations,
AllViolations = allViolations,
OverallScore = CalculateScore(allViolations),
Summary = GenerateViolationSummary(allViolations)
};
}
/// <summary>
/// 验证系统配置
/// </summary>
/// <returns>系统级违规列表</returns>
private static List<BestPracticeViolation> ValidateSystemConfiguration()
{
var violations = new List<BestPracticeViolation>();
// 检查性能监控
violations.AddRange(ValidateObject("system_performance"));
// 检查绑定优化器
violations.AddRange(ValidateObject("system_binding"));
// 检查同步器
violations.AddRange(ValidateObject("system_sync"));
return violations.Where(v => v != null).ToList();
}
/// <summary>
/// 计算合规性评分
/// </summary>
/// <param name="violations">违规列表</param>
/// <returns>评分 (0-100)</returns>
private static int CalculateScore(List<BestPracticeViolation> violations)
{
if (violations.Count == 0)
return 100;
var errorCount = violations.Count(v => v.Severity == RuleSeverity.Error);
var warningCount = violations.Count(v => v.Severity == RuleSeverity.Warning);
var infoCount = violations.Count(v => v.Severity == RuleSeverity.Information);
// 错误-30分警告-10分信息-2分
var deduction = errorCount * 30 + warningCount * 10 + infoCount * 2;
return Math.Max(0, 100 - deduction);
}
/// <summary>
/// 生成违规汇总
/// </summary>
/// <param name="violations">违规列表</param>
/// <returns>汇总信息</returns>
private static ViolationSummary GenerateViolationSummary(List<BestPracticeViolation> violations)
{
var summary = new ViolationSummary();
foreach (BestPracticeCategory category in Enum.GetValues(typeof(BestPracticeCategory)))
{
var categoryViolations = violations.Where(v =>
Rules.FirstOrDefault(r => r.Id == v.RuleId)?.Category == (BestPracticeCategory)category).ToList();
summary.ByCategory[category] = new CategorySummary
{
TotalCount = categoryViolations.Count,
ErrorCount = categoryViolations.Count(v => v.Severity == RuleSeverity.Error),
WarningCount = categoryViolations.Count(v => v.Severity == RuleSeverity.Warning),
InfoCount = categoryViolations.Count(v => v.Severity == RuleSeverity.Information)
};
}
summary.TotalViolations = violations.Count;
summary.MostCommonViolations = violations
.GroupBy(v => v.RuleId)
.OrderByDescending(g => g.Count())
.Take(5)
.ToDictionary(g => g.Key, g => g.Count());
return summary;
}
/// <summary>
/// 生成最佳实践报告文档
/// </summary>
/// <param name="report">验证报告</param>
/// <returns>报告文档</returns>
public static string GenerateReportDocument(ApplicationBestPracticeReport report)
{
var doc = new StringBuilder();
doc.AppendLine("# 数据绑定最佳实践验证报告");
doc.AppendLine($"生成时间: {report.ValidationTime:yyyy-MM-dd HH:mm:ss}");
doc.AppendLine($"总体评分: {report.OverallScore}/100");
doc.AppendLine();
// 执行摘要
doc.AppendLine("## 执行摘要");
doc.AppendLine($"- 验证的ViewModel数量: {report.ViewModelReports.Count}");
doc.AppendLine($"- 发现的问题总数: {report.AllViolations.Count}");
doc.AppendLine($"- 错误: {report.Summary.ByCategory.Values.Sum(c => c.ErrorCount)}");
doc.AppendLine($"- 警告: {report.Summary.ByCategory.Values.Sum(c => c.WarningCount)}");
doc.AppendLine($"- 信息: {report.Summary.ByCategory.Values.Sum(c => c.InfoCount)}");
doc.AppendLine();
// 按类别分组的问题
doc.AppendLine("## 问题分类统计");
foreach (var kvp in report.Summary.ByCategory)
{
if (kvp.Value.TotalCount > 0)
{
doc.AppendLine($"### {kvp.Key}");
doc.AppendLine($"- 总计: {kvp.Value.TotalCount}");
doc.AppendLine($"- 错误: {kvp.Value.ErrorCount}");
doc.AppendLine($"- 警告: {kvp.Value.WarningCount}");
doc.AppendLine($"- 信息: {kvp.Value.InfoCount}");
doc.AppendLine();
}
}
// 最常见问题
doc.AppendLine("## 最常见问题");
foreach (var kvp in report.Summary.MostCommonViolations)
{
var rule = Rules.FirstOrDefault(r => r.Id == kvp.Key);
if (rule != null)
{
doc.AppendLine($"- **{rule.Title}** ({kvp.Key}): {kvp.Value}次");
doc.AppendLine($" {rule.Description}");
doc.AppendLine();
}
}
// 详细问题列表
doc.AppendLine("## 详细问题列表");
var violationsByViewModel = report.ViewModelReports
.Where(r => r.Violations.Count > 0)
.OrderByDescending(r => r.Violations.Count);
foreach (var vmReport in violationsByViewModel)
{
doc.AppendLine($"### {vmReport.TargetType.Name}");
doc.AppendLine($"评分: {vmReport.OverallScore}/100");
doc.AppendLine();
foreach (var violation in vmReport.Violations.OrderByDescending(v => v.Severity))
{
var severityIcon = "";
switch (violation.Severity)
{
case RuleSeverity.Error:
severityIcon = "❌";
break;
case RuleSeverity.Warning:
severityIcon = "⚠️";
break;
case RuleSeverity.Information:
severityIcon = "";
break;
default:
severityIcon = "•";
break;
}
doc.AppendLine($"{severityIcon} **{violation.RuleId}**: {violation.Message}");
doc.AppendLine($" 💡 建议: {violation.Recommendation}");
doc.AppendLine();
}
}
// 优化建议
doc.AppendLine("## 优化建议");
doc.AppendLine(GenerateOptimizationRecommendations(report));
return doc.ToString();
}
/// <summary>
/// 生成优化建议
/// </summary>
/// <param name="report">验证报告</param>
/// <returns>优化建议</returns>
private static string GenerateOptimizationRecommendations(ApplicationBestPracticeReport report)
{
var recommendations = new StringBuilder();
// 基于违规情况生成针对性建议
var errorCount = report.AllViolations.Count(v => v.Severity == RuleSeverity.Error);
var warningCount = report.AllViolations.Count(v => v.Severity == RuleSeverity.Warning);
if (errorCount > 0)
{
recommendations.AppendLine("### 高优先级 (必须修复)");
recommendations.AppendLine("1. 修复所有错误级别的问题,这些问题可能导致运行时错误或严重的性能问题");
recommendations.AppendLine("2. 确保所有ViewModel继承ViewModelBase基类");
recommendations.AppendLine("3. 使用线程安全的集合类型");
recommendations.AppendLine();
}
if (warningCount > 0)
{
recommendations.AppendLine("### 中等优先级 (建议修复)");
recommendations.AppendLine("1. 解决警告级别的问题以提高应用性能");
recommendations.AppendLine("2. 对大集合启用虚拟化");
recommendations.AppendLine("3. 优化频繁更新的属性");
recommendations.AppendLine();
}
recommendations.AppendLine("### 一般建议");
recommendations.AppendLine("1. 在开发阶段启用性能监控以及时发现问题");
recommendations.AppendLine("2. 定期运行最佳实践验证");
recommendations.AppendLine("3. 建立代码审查流程确保新代码符合最佳实践");
recommendations.AppendLine("4. 为团队成员提供数据绑定最佳实践培训");
return recommendations.ToString();
}
#endregion
#region
/// <summary>
/// 获取自动修复建议
/// </summary>
/// <param name="violation">违规项</param>
/// <returns>修复建议</returns>
public static AutoFixSuggestion GetAutoFixSuggestion(BestPracticeViolation violation)
{
switch (violation.RuleId)
{
case "VM01":
return new AutoFixSuggestion
{
CanAutoFix = false,
Description = "需要手动修改类继承关系",
Steps = new[]
{
"1. 添加using NavisworksTransport.UI.WPF.ViewModels;",
"2. 修改类定义: public class MyViewModel : ViewModelBase",
"3. 移除手动实现的INotifyPropertyChanged相关代码"
}
};
case "COL01":
return new AutoFixSuggestion
{
CanAutoFix = true,
Description = "可以自动替换为线程安全集合",
Steps = new[]
{
"1. 替换ObservableCollection<T>为ThreadSafeObservableCollection<T>",
"2. 添加using NavisworksTransport.UI.WPF.Collections;"
}
};
case "COL02":
return new AutoFixSuggestion
{
CanAutoFix = true,
Description = "可以自动替换为虚拟化集合",
Steps = new[]
{
"1. 替换为VirtualizedObservableCollection<T>",
"2. 实现IVirtualDataProvider<T>接口"
}
};
default:
return new AutoFixSuggestion
{
CanAutoFix = false,
Description = "需要手动修复",
Steps = new[] { violation.Recommendation }
};
}
}
#endregion
}
#region
/// <summary>
/// 最佳实践规则
/// </summary>
public class BestPracticeRule
{
public string Id { get; set; }
public BestPracticeCategory Category { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public RuleSeverity Severity { get; set; }
public Func<object, BestPracticeViolation> CheckAction { get; set; }
}
/// <summary>
/// 最佳实践违规
/// </summary>
public class BestPracticeViolation
{
public string RuleId { get; set; }
public string Message { get; set; }
public string Recommendation { get; set; }
public RuleSeverity Severity { get; set; }
public object Context { get; set; }
}
/// <summary>
/// 最佳实践报告
/// </summary>
public class BestPracticeReport
{
public object TargetObject { get; set; }
public Type TargetType { get; set; }
public DateTime ValidationTime { get; set; }
public List<BestPracticeViolation> Violations { get; set; } = new List<BestPracticeViolation>();
public int OverallScore { get; set; }
}
/// <summary>
/// 应用最佳实践报告
/// </summary>
public class ApplicationBestPracticeReport
{
public DateTime ValidationTime { get; set; }
public List<BestPracticeReport> ViewModelReports { get; set; } = new List<BestPracticeReport>();
public List<BestPracticeViolation> SystemViolations { get; set; } = new List<BestPracticeViolation>();
public List<BestPracticeViolation> AllViolations { get; set; } = new List<BestPracticeViolation>();
public int OverallScore { get; set; }
public ViolationSummary Summary { get; set; }
}
/// <summary>
/// 违规汇总
/// </summary>
public class ViolationSummary
{
public Dictionary<BestPracticeCategory, CategorySummary> ByCategory { get; set; } = new Dictionary<BestPracticeCategory, CategorySummary>();
public int TotalViolations { get; set; }
public Dictionary<string, int> MostCommonViolations { get; set; } = new Dictionary<string, int>();
}
/// <summary>
/// 类别汇总
/// </summary>
public class CategorySummary
{
public int TotalCount { get; set; }
public int ErrorCount { get; set; }
public int WarningCount { get; set; }
public int InfoCount { get; set; }
}
/// <summary>
/// 自动修复建议
/// </summary>
public class AutoFixSuggestion
{
public bool CanAutoFix { get; set; }
public string Description { get; set; }
public string[] Steps { get; set; }
}
/// <summary>
/// 最佳实践类别
/// </summary>
public enum BestPracticeCategory
{
ViewModel,
Collections,
Binding,
Synchronization,
Memory,
Performance
}
/// <summary>
/// 规则严重性
/// </summary>
public enum RuleSeverity
{
Information = 0,
Warning = 1,
Error = 2
}
#endregion
}