Skip to content

Commit 949d9be

Browse files
BornToBeRootclaude
andcommitted
Fix: Settings lists not saved after the settings were loaded
The CollectionChanged handlers were only attached to the initial collections in the constructor. Since the settings are stored as JSON (#3282), System.Text.Json replaces the collections when loading, and some views replace them at runtime (e.g. PuTTY/PowerShell histories, reset to defaults), so changes to these lists no longer marked the settings as changed and were lost if nothing else changed. Each collection setter now moves the handler to the new collection. Also adds the missing handler for Network_CustomDNSServers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 4acaaeb commit 949d9be

2 files changed

Lines changed: 61 additions & 0 deletions

File tree

‎Source/NETworkManager.Settings/SettingsInfo.cs‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ public ObservableSetCollection<ApplicationInfo> General_ApplicationList
135135
if (value == field)
136136
return;
137137

138+
UpdateCollectionChanged(field, value);
138139
field = value;
139140
OnPropertyChanged();
140141
}
@@ -398,6 +399,7 @@ public ObservableCollection<ServerConnectionInfo> Network_CustomDNSServers
398399
if (value == field)
399400
return;
400401

402+
UpdateCollectionChanged(field, value);
401403
field = value;
402404
OnPropertyChanged();
403405
}
@@ -1158,6 +1160,7 @@ public ObservableCollection<string> IPScanner_HostHistory
11581160
if (value == field)
11591161
return;
11601162

1163+
UpdateCollectionChanged(field, value);
11611164
field = value;
11621165
OnPropertyChanged();
11631166
}
@@ -1262,6 +1265,7 @@ public ObservableCollection<CustomCommandInfo> IPScanner_CustomCommands
12621265
if (value == field)
12631266
return;
12641267

1268+
UpdateCollectionChanged(field, value);
12651269
field = value;
12661270
OnPropertyChanged();
12671271
}
@@ -1331,6 +1335,7 @@ public ObservableCollection<string> PortScanner_HostHistory
13311335
if (value == field)
13321336
return;
13331337

1338+
UpdateCollectionChanged(field, value);
13341339
field = value;
13351340
OnPropertyChanged();
13361341
}
@@ -1344,6 +1349,7 @@ public ObservableCollection<string> PortScanner_PortHistory
13441349
if (value == field)
13451350
return;
13461351

1352+
UpdateCollectionChanged(field, value);
13471353
field = value;
13481354
OnPropertyChanged();
13491355
}
@@ -1357,6 +1363,7 @@ public ObservableCollection<PortProfileInfo> PortScanner_PortProfiles
13571363
if (value == field)
13581364
return;
13591365

1366+
UpdateCollectionChanged(field, value);
13601367
field = value;
13611368
OnPropertyChanged();
13621369
}
@@ -1465,6 +1472,7 @@ public ObservableCollection<string> PingMonitor_HostHistory
14651472
if (value == field)
14661473
return;
14671474

1475+
UpdateCollectionChanged(field, value);
14681476
field = value;
14691477
OnPropertyChanged();
14701478
}
@@ -1664,6 +1672,7 @@ public ObservableCollection<string> Traceroute_HostHistory
16641672
if (value == field)
16651673
return;
16661674

1675+
UpdateCollectionChanged(field, value);
16671676
field = value;
16681677
OnPropertyChanged();
16691678
}
@@ -1811,6 +1820,7 @@ public ObservableCollection<string> DNSLookup_HostHistory
18111820
if (value == field)
18121821
return;
18131822

1823+
UpdateCollectionChanged(field, value);
18141824
field = value;
18151825
OnPropertyChanged();
18161826
}
@@ -1824,6 +1834,7 @@ public ObservableCollection<DNSServerConnectionInfoProfile> DNSLookup_DNSServers
18241834
if (value == field)
18251835
return;
18261836

1837+
UpdateCollectionChanged(field, value);
18271838
field = value;
18281839
OnPropertyChanged();
18291840
}
@@ -2025,6 +2036,7 @@ public ObservableCollection<string> RemoteDesktop_HostHistory
20252036
if (value == field)
20262037
return;
20272038

2039+
UpdateCollectionChanged(field, value);
20282040
field = value;
20292041
OnPropertyChanged();
20302042
}
@@ -2510,6 +2522,7 @@ public ObservableCollection<string> PowerShell_HostHistory
25102522
if (value == field)
25112523
return;
25122524

2525+
UpdateCollectionChanged(field, value);
25132526
field = value;
25142527
OnPropertyChanged();
25152528
}
@@ -2579,6 +2592,7 @@ public ObservableCollection<string> PuTTY_HostHistory
25792592
if (value == field)
25802593
return;
25812594

2595+
UpdateCollectionChanged(field, value);
25822596
field = value;
25832597
OnPropertyChanged();
25842598
}
@@ -2709,6 +2723,7 @@ public ObservableCollection<string> PuTTY_SerialLineHistory
27092723
if (value == field)
27102724
return;
27112725

2726+
UpdateCollectionChanged(field, value);
27122727
field = value;
27132728
OnPropertyChanged();
27142729
}
@@ -2722,6 +2737,7 @@ public ObservableCollection<string> PuTTY_PortHistory
27222737
if (value == field)
27232738
return;
27242739

2740+
UpdateCollectionChanged(field, value);
27252741
field = value;
27262742
OnPropertyChanged();
27272743
}
@@ -2735,6 +2751,7 @@ public ObservableCollection<string> PuTTY_BaudHistory
27352751
if (value == field)
27362752
return;
27372753

2754+
UpdateCollectionChanged(field, value);
27382755
field = value;
27392756
OnPropertyChanged();
27402757
}
@@ -2748,6 +2765,7 @@ public ObservableCollection<string> PuTTY_UsernameHistory
27482765
if (value == field)
27492766
return;
27502767

2768+
UpdateCollectionChanged(field, value);
27512769
field = value;
27522770
OnPropertyChanged();
27532771
}
@@ -2761,6 +2779,7 @@ public ObservableCollection<string> PuTTY_PrivateKeyFileHistory
27612779
if (value == field)
27622780
return;
27632781

2782+
UpdateCollectionChanged(field, value);
27642783
field = value;
27652784
OnPropertyChanged();
27662785
}
@@ -2774,6 +2793,7 @@ public ObservableCollection<string> PuTTY_ProfileHistory
27742793
if (value == field)
27752794
return;
27762795

2796+
UpdateCollectionChanged(field, value);
27772797
field = value;
27782798
OnPropertyChanged();
27792799
}
@@ -2883,6 +2903,7 @@ public ObservableCollection<string> TigerVNC_HostHistory
28832903
if (value == field)
28842904
return;
28852905

2906+
UpdateCollectionChanged(field, value);
28862907
field = value;
28872908
OnPropertyChanged();
28882909
}
@@ -2896,6 +2917,7 @@ public ObservableCollection<int> TigerVNC_PortHistory
28962917
if (value == field)
28972918
return;
28982919

2920+
UpdateCollectionChanged(field, value);
28992921
field = value;
29002922
OnPropertyChanged();
29012923
}
@@ -2939,6 +2961,7 @@ public ObservableCollection<string> WebConsole_UrlHistory
29392961
if (value == field)
29402962
return;
29412963

2964+
UpdateCollectionChanged(field, value);
29422965
field = value;
29432966
OnPropertyChanged();
29442967
}
@@ -2995,6 +3018,7 @@ public ObservableCollection<string> SNMP_HostHistory
29953018
if (value == field)
29963019
return;
29973020

3021+
UpdateCollectionChanged(field, value);
29983022
field = value;
29993023
OnPropertyChanged();
30003024
}
@@ -3008,6 +3032,7 @@ public ObservableCollection<string> SNMP_OidHistory
30083032
if (value == field)
30093033
return;
30103034

3035+
UpdateCollectionChanged(field, value);
30113036
field = value;
30123037
OnPropertyChanged();
30133038
}
@@ -3021,6 +3046,7 @@ public ObservableCollection<SNMPOIDProfileInfo> SNMP_OidProfiles
30213046
if (value == field)
30223047
return;
30233048

3049+
UpdateCollectionChanged(field, value);
30243050
field = value;
30253051
OnPropertyChanged();
30263052
}
@@ -3169,6 +3195,7 @@ public ObservableCollection<ServerConnectionInfoProfile> SNTPLookup_SNTPServers
31693195
if (value == field)
31703196
return;
31713197

3198+
UpdateCollectionChanged(field, value);
31723199
field = value;
31733200
OnPropertyChanged();
31743201
}
@@ -3366,6 +3393,7 @@ public ObservableCollection<string> WakeOnLan_MACAddressHistory
33663393
if (value == field)
33673394
return;
33683395

3396+
UpdateCollectionChanged(field, value);
33693397
field = value;
33703398
OnPropertyChanged();
33713399
}
@@ -3379,6 +3407,7 @@ public ObservableCollection<string> WakeOnLan_BroadcastHistory
33793407
if (value == field)
33803408
return;
33813409

3410+
UpdateCollectionChanged(field, value);
33823411
field = value;
33833412
OnPropertyChanged();
33843413
}
@@ -3396,6 +3425,7 @@ public ObservableCollection<string> RDAP_QueryHistory
33963425
if (value == field)
33973426
return;
33983427

3428+
UpdateCollectionChanged(field, value);
33993429
field = value;
34003430
OnPropertyChanged();
34013431
}
@@ -3478,6 +3508,7 @@ public ObservableCollection<string> Whois_DomainHistory
34783508
if (value == field)
34793509
return;
34803510

3511+
UpdateCollectionChanged(field, value);
34813512
field = value;
34823513
OnPropertyChanged();
34833514
}
@@ -3521,6 +3552,7 @@ public ObservableCollection<string> IPGeolocation_HostHistory
35213552
if (value == field)
35223553
return;
35233554

3555+
UpdateCollectionChanged(field, value);
35243556
field = value;
35253557
OnPropertyChanged();
35263558
}
@@ -3566,6 +3598,7 @@ public ObservableCollection<string> SubnetCalculator_Calculator_SubnetHistory
35663598
if (value == field)
35673599
return;
35683600

3601+
UpdateCollectionChanged(field, value);
35693602
field = value;
35703603
OnPropertyChanged();
35713604
}
@@ -3583,6 +3616,7 @@ public ObservableCollection<string> SubnetCalculator_Subnetting_SubnetHistory
35833616
if (value == field)
35843617
return;
35853618

3619+
UpdateCollectionChanged(field, value);
35863620
field = value;
35873621
OnPropertyChanged();
35883622
}
@@ -3596,6 +3630,7 @@ public ObservableCollection<string> SubnetCalculator_Subnetting_NewSubnetmaskHis
35963630
if (value == field)
35973631
return;
35983632

3633+
UpdateCollectionChanged(field, value);
35993634
field = value;
36003635
OnPropertyChanged();
36013636
}
@@ -3639,6 +3674,7 @@ public ObservableCollection<string> SubnetCalculator_WideSubnet_Subnet1
36393674
if (value == field)
36403675
return;
36413676

3677+
UpdateCollectionChanged(field, value);
36423678
field = value;
36433679
OnPropertyChanged();
36443680
}
@@ -3652,6 +3688,7 @@ public ObservableCollection<string> SubnetCalculator_WideSubnet_Subnet2
36523688
if (value == field)
36533689
return;
36543690

3691+
UpdateCollectionChanged(field, value);
36553692
field = value;
36563693
OnPropertyChanged();
36573694
}
@@ -3671,6 +3708,7 @@ public ObservableCollection<string> BitCalculator_InputHistory
36713708
if (value == field)
36723709
return;
36733710

3711+
UpdateCollectionChanged(field, value);
36743712
field = value;
36753713
OnPropertyChanged();
36763714
}
@@ -3741,6 +3779,7 @@ public ObservableCollection<string> Lookup_OUI_SearchHistory
37413779
if (value == field)
37423780
return;
37433781

3782+
UpdateCollectionChanged(field, value);
37443783
field = value;
37453784
OnPropertyChanged();
37463785
}
@@ -3780,6 +3819,7 @@ public ObservableCollection<string> Lookup_Port_SearchHistory
37803819
if (value == field)
37813820
return;
37823821

3822+
UpdateCollectionChanged(field, value);
37833823
field = value;
37843824
OnPropertyChanged();
37853825
}
@@ -4003,6 +4043,9 @@ public SettingsInfo()
40034043
// General
40044044
General_ApplicationList.CollectionChanged += CollectionChanged;
40054045

4046+
// Network
4047+
Network_CustomDNSServers.CollectionChanged += CollectionChanged;
4048+
40064049
// IP Scanner
40074050
IPScanner_HostHistory.CollectionChanged += CollectionChanged;
40084051
IPScanner_CustomCommands.CollectionChanged += CollectionChanged;
@@ -4091,5 +4134,21 @@ private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e
40914134
SettingsChanged = true;
40924135
}
40934136

4137+
/// <summary>
4138+
/// Moves the <see cref="CollectionChanged" /> handler from the old to the new collection, if a collection property
4139+
/// is replaced (e.g. when the settings are loaded from the JSON file or a history is rebuilt). Otherwise, changes
4140+
/// to the new collection would not mark the settings as changed and would not be saved.
4141+
/// </summary>
4142+
/// <param name="oldCollection">Collection that is replaced.</param>
4143+
/// <param name="newCollection">New collection.</param>
4144+
private void UpdateCollectionChanged(INotifyCollectionChanged oldCollection, INotifyCollectionChanged newCollection)
4145+
{
4146+
if (oldCollection != null)
4147+
oldCollection.CollectionChanged -= CollectionChanged;
4148+
4149+
if (newCollection != null)
4150+
newCollection.CollectionChanged += CollectionChanged;
4151+
}
4152+
40944153
#endregion
40954154
}

‎Website/docs/changelog/next-release.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ Release date: **xx.xx.2026**
7676

7777
## Bug Fixes
7878

79+
- Fixed changes to lists in the settings (e.g. query histories, port profiles, custom commands) not being saved if no other setting was changed in the same session. This happened since the settings are stored as JSON. [#3607](https://github.com/BornToBeRoot/NETworkManager/pull/3607)
80+
7981
**Dashboard**
8082

8183
- Fixed the **Network Connection** widget running a full connection check on every application startup, even if the Status Window or Dashboard was never opened. It now only checks when actually shown - via the tray icon, on a network change, or when the Dashboard tab is opened. [#3553](https://github.com/BornToBeRoot/NETworkManager/pull/3553)

0 commit comments

Comments
 (0)