Browse Source

Assembly list switching in toolbar

- Hold AssemblyListManager on AssemblyTreeModel and mirror its
  AssemblyLists collection so the toolbar combo can bind to it.
- New ActiveListName ([ObservableProperty]); OnActiveListNameChanged
  loads the named list via the manager and rebuilds Root.
- The "seed initial assemblies if empty" fallback now only triggers
  for the (Default) list, so switching to an empty user list doesn't
  auto-populate it.
- MainToolBar AssemblyListComboBox bound to AssemblyLists /
  ActiveListName (TwoWay).

Assisted-by: Claude:claude-opus-4-7:Claude Code
pull/3755/head
Siegfried Pammer 2 months ago
parent
commit
1da17ba9c0
  1. 14
      ILSpy.Tests/AssemblyTree/AssemblyTreeModelTests.cs
  2. 36
      ILSpy/AssemblyTree/AssemblyTreeModel.cs
  3. 11
      ILSpy/Views/MainToolBar.axaml

14
ILSpy.Tests/AssemblyTree/AssemblyTreeModelTests.cs

@ -20,6 +20,8 @@ using Avalonia.Headless.NUnit; @@ -20,6 +20,8 @@ using Avalonia.Headless.NUnit;
using AwesomeAssertions;
using ICSharpCode.ILSpyX;
using ILSpy.AppEnv;
using ILSpy.AssemblyTree;
@ -46,4 +48,16 @@ public class AssemblyTreeModelTests @@ -46,4 +48,16 @@ public class AssemblyTreeModelTests
model.AssemblyList.Should().NotBeNull("Initialize loads or creates the default AssemblyList.");
model.Root.Should().NotBeNull("Initialize wires Root to an AssemblyListTreeNode of the loaded list.");
}
[AvaloniaTest]
public void Initialize_populates_AssemblyLists_and_selects_the_default()
{
var model = AppComposition.Current.GetExport<AssemblyTreeModel>();
model.Initialize();
model.AssemblyLists.Should().NotBeEmpty(
"Initialize mirrors AssemblyListManager.AssemblyLists into the toolbar combo's source.");
model.ActiveListName.Should().Be(AssemblyListManager.DefaultListName,
"Initialize selects the (Default) list so the tree has something to render at startup.");
}
}

36
ILSpy/AssemblyTree/AssemblyTreeModel.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.ObjectModel;
using System.Composition;
using System.Runtime.Serialization;
@ -37,6 +38,8 @@ namespace ILSpy.AssemblyTree @@ -37,6 +38,8 @@ namespace ILSpy.AssemblyTree
{
public const string PaneContentId = "AssemblyTree";
AssemblyListManager? listManager;
[ObservableProperty]
[property: IgnoreDataMember]
private SharpTreeNode? root;
@ -45,9 +48,16 @@ namespace ILSpy.AssemblyTree @@ -45,9 +48,16 @@ namespace ILSpy.AssemblyTree
[property: IgnoreDataMember]
private SharpTreeNode? selectedItem;
[ObservableProperty]
[property: IgnoreDataMember]
private string? activeListName;
[IgnoreDataMember]
public AssemblyList? AssemblyList { get; private set; }
[IgnoreDataMember]
public ObservableCollection<string> AssemblyLists { get; } = [];
public AssemblyTreeModel()
{
Id = PaneContentId;
@ -58,12 +68,32 @@ namespace ILSpy.AssemblyTree @@ -58,12 +68,32 @@ namespace ILSpy.AssemblyTree
public void Initialize()
{
var settings = ILSpySettings.Load();
var listManager = new AssemblyListManager(settings);
listManager = new AssemblyListManager(settings);
listManager.CreateDefaultAssemblyLists();
AssemblyList = listManager.LoadList(AssemblyListManager.DefaultListName);
SyncListNames();
listManager.AssemblyLists.CollectionChanged += (_, _) => SyncListNames();
ActiveListName = AssemblyListManager.DefaultListName;
}
void SyncListNames()
{
if (listManager == null)
return;
AssemblyLists.Clear();
foreach (var name in listManager.AssemblyLists)
AssemblyLists.Add(name);
}
partial void OnActiveListNameChanged(string? value)
{
if (listManager == null || string.IsNullOrEmpty(value))
return;
AssemblyList = listManager.LoadList(value);
if (AssemblyList.GetAssemblies().Length == 0)
if (AssemblyList.GetAssemblies().Length == 0 && value == AssemblyListManager.DefaultListName)
LoadInitialAssemblies(AssemblyList);
var rootNode = new AssemblyListTreeNode(AssemblyList);

11
ILSpy/Views/MainToolBar.axaml

@ -2,16 +2,19 @@ @@ -2,16 +2,19 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:ILSpy.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="30"
x:Class="ILSpy.MainToolBar">
x:Class="ILSpy.MainToolBar"
x:DataType="vm:MainWindowViewModel">
<StackPanel Orientation="Horizontal" Height="30">
<!-- Navigation category (Back/Forward) inserted by MEF (task #10) -->
<Separator />
<!-- Open category inserted by MEF (task #10) -->
<Separator />
<!-- Assembly list combobox (task #6 / #11) -->
<ComboBox Name="AssemblyListComboBox" Margin="2,0"
ToolTip.Tip="Select an assembly list" />
<ComboBox Name="AssemblyListComboBox" Margin="2,0" MinWidth="160"
ToolTip.Tip="Select an assembly list"
ItemsSource="{Binding AssemblyTreeModel.AssemblyLists}"
SelectedItem="{Binding AssemblyTreeModel.ActiveListName, Mode=TwoWay}" />
<Separator />
<!-- Language selector (task #8) -->
<ComboBox Name="LanguageComboBox" Margin="2,0"

Loading…
Cancel
Save