diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67cf250..44c477f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,14 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+## [1.17.3] - 2026-05-29
+
+### Fixed
+- **Performance** — NetworkSharedState TracerouteHops converted to BulkObservableCollection with ReplaceWith() (eliminates per-hop UI notifications during route updates).
+- **Performance** — ServicesViewModel safety level counts now computed in a single pass instead of 3 separate LINQ queries.
+- **Consistency** — DnsHostsView removed stale `HorizontalGridLinesBrush` property (no visual impact, code cleanliness).
+- **Consistency** — AppBlockerView DataGrid BorderThickness set to 0 matching all other views.
+
## [1.17.2] - 2026-05-29
### Fixed
diff --git a/SysManager/SysManager/SysManager.csproj b/SysManager/SysManager/SysManager.csproj
index 350dc2e..5212f82 100644
--- a/SysManager/SysManager/SysManager.csproj
+++ b/SysManager/SysManager/SysManager.csproj
@@ -10,9 +10,9 @@
SysManager
true
NU1603;NU1701
- 1.17.2
- 1.17.2.0
- 1.17.2.0
+ 1.17.3
+ 1.17.3.0
+ 1.17.3.0
SysManager
SysManager — Windows system monitoring toolkit by laurentiu021. Network, updates, health, logs, safe deep cleanup.
https://github.com/laurentiu021/SystemManager
diff --git a/SysManager/SysManager/ViewModels/NetworkSharedState.cs b/SysManager/SysManager/ViewModels/NetworkSharedState.cs
index bd1e16b..c4eb339 100644
--- a/SysManager/SysManager/ViewModels/NetworkSharedState.cs
+++ b/SysManager/SysManager/ViewModels/NetworkSharedState.cs
@@ -50,7 +50,7 @@ public sealed partial class NetworkSharedState : ObservableObject, IDisposable
private readonly Dictionary _targetHandlers = new();
public ObservableCollection Targets { get; } = new();
- public ObservableCollection TracerouteHops { get; } = new();
+ public BulkObservableCollection TracerouteHops { get; } = new();
// ── Chart infrastructure ──
public ObservableCollection LatencySeries { get; } = new();
@@ -470,10 +470,10 @@ internal void ApplyRoute(string host, IReadOnlyList hops)
internal void RefreshHopTable()
{
- TracerouteHops.Clear();
- foreach (var target in Targets.Where(t => LatestRoutes.ContainsKey(t.Host)))
- foreach (var h in LatestRoutes[target.Host])
- TracerouteHops.Add(h);
+ var hops = Targets
+ .Where(t => LatestRoutes.ContainsKey(t.Host))
+ .SelectMany(t => LatestRoutes[t.Host]);
+ TracerouteHops.ReplaceWith(hops);
}
internal void TrimBuffer(BulkObservableCollection buffer)
diff --git a/SysManager/SysManager/ViewModels/ServicesViewModel.cs b/SysManager/SysManager/ViewModels/ServicesViewModel.cs
index c74e3f6..c9ff066 100644
--- a/SysManager/SysManager/ViewModels/ServicesViewModel.cs
+++ b/SysManager/SysManager/ViewModels/ServicesViewModel.cs
@@ -191,9 +191,19 @@ private void ApplyFilter()
Services.ReplaceWith(filtered.OrderBy(s => s.DisplayName, StringComparer.OrdinalIgnoreCase));
- SafeCount = _allServices.Count(s => s.SafetyLevel == SafetyLevel.Safe);
- CautionCount = _allServices.Count(s => s.SafetyLevel == SafetyLevel.Caution);
- CriticalCount = _allServices.Count(s => s.SafetyLevel == SafetyLevel.Critical);
+ int safe = 0, caution = 0, critical = 0;
+ foreach (var s in _allServices)
+ {
+ switch (s.SafetyLevel)
+ {
+ case SafetyLevel.Safe: safe++; break;
+ case SafetyLevel.Caution: caution++; break;
+ case SafetyLevel.Critical: critical++; break;
+ }
+ }
+ SafeCount = safe;
+ CautionCount = caution;
+ CriticalCount = critical;
}
[RelayCommand]
diff --git a/SysManager/SysManager/Views/AppBlockerView.xaml b/SysManager/SysManager/Views/AppBlockerView.xaml
index d5b72c5..af0b88d 100644
--- a/SysManager/SysManager/Views/AppBlockerView.xaml
+++ b/SysManager/SysManager/Views/AppBlockerView.xaml
@@ -79,7 +79,7 @@
CanUserAddRows="False" CanUserDeleteRows="False"
CanUserResizeColumns="True"
HeadersVisibility="Column" GridLinesVisibility="None"
- BorderThickness="1" BorderBrush="{DynamicResource Border1}"
+ BorderThickness="0"
Background="Transparent"
AutomationProperties.Name="Data table"
VirtualizingPanel.IsVirtualizing="True"
diff --git a/SysManager/SysManager/Views/DnsHostsView.xaml b/SysManager/SysManager/Views/DnsHostsView.xaml
index c596cf9..bc69ad2 100644
--- a/SysManager/SysManager/Views/DnsHostsView.xaml
+++ b/SysManager/SysManager/Views/DnsHostsView.xaml
@@ -121,7 +121,6 @@
Background="Transparent"
AutomationProperties.Name="Data table"
Foreground="{DynamicResource TextPrimary}" FontSize="12"
- HorizontalGridLinesBrush="#1E293B"
SelectionMode="Single" IsReadOnly="False"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling">