diff --git a/XSDVisualiser.Desktop/MainWindow.axaml b/XSDVisualiser.Desktop/MainWindow.axaml
index 6c4fb51..a016ac3 100644
--- a/XSDVisualiser.Desktop/MainWindow.axaml
+++ b/XSDVisualiser.Desktop/MainWindow.axaml
@@ -16,6 +16,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -26,7 +42,7 @@
BorderBrush="{DynamicResource PanelBorderBrush}"
BorderThickness="1" CornerRadius="6" Margin="0,8,8,0">
-
+
diff --git a/XSDVisualiser.Desktop/MainWindow.axaml.cs b/XSDVisualiser.Desktop/MainWindow.axaml.cs
index 0a65705..4d3dcf7 100644
--- a/XSDVisualiser.Desktop/MainWindow.axaml.cs
+++ b/XSDVisualiser.Desktop/MainWindow.axaml.cs
@@ -5,6 +5,7 @@ using Avalonia.Interactivity;
using Avalonia.Threading;
using XSDVisualiser.Core;
using XSDVisualiser.Models;
+using XSDVisualiser.Desktop.ViewModels;
namespace XSDVisualiser.Desktop
{
@@ -42,11 +43,11 @@ namespace XSDVisualiser.Desktop
{
var parser = new XsdSchemaParser();
var model = parser.Parse(path);
- Dispatcher.UIThread.Post(() => DataContext = model);
+ Dispatcher.UIThread.Post(() => DataContext = new MainWindowViewModel(model));
}
catch (Exception ex)
{
- Dispatcher.UIThread.Post(() => DataContext = new SchemaModel { TargetNamespace = ex.Message });
+ Dispatcher.UIThread.Post(() => DataContext = new MainWindowViewModel(new SchemaModel { TargetNamespace = ex.Message }));
}
});
}
diff --git a/XSDVisualiser.Desktop/ViewModels/MainWindowViewModel.cs b/XSDVisualiser.Desktop/ViewModels/MainWindowViewModel.cs
new file mode 100644
index 0000000..8a0e2fb
--- /dev/null
+++ b/XSDVisualiser.Desktop/ViewModels/MainWindowViewModel.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using XSDVisualiser.Models;
+
+namespace XSDVisualiser.Desktop.ViewModels
+{
+ public class MainWindowViewModel : INotifyPropertyChanged
+ {
+ private SchemaModel _model;
+ private SchemaNode? _selectedRootElement;
+
+ public MainWindowViewModel(SchemaModel model)
+ {
+ _model = model ?? throw new ArgumentNullException(nameof(model));
+ }
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ private void OnPropertyChanged([CallerMemberName] string? name = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public SchemaModel Model
+ {
+ get => _model;
+ set
+ {
+ if (!ReferenceEquals(_model, value))
+ {
+ _model = value ?? throw new ArgumentNullException(nameof(value));
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(RootElements));
+ OnPropertyChanged(nameof(VisibleRootElements));
+ }
+ }
+ }
+
+ public IEnumerable RootElements => _model?.RootElements ?? Enumerable.Empty();
+
+ public SchemaNode? SelectedRootElement
+ {
+ get => _selectedRootElement;
+ set
+ {
+ if (!EqualityComparer.Default.Equals(_selectedRootElement, value))
+ {
+ _selectedRootElement = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(VisibleRootElements));
+ }
+ }
+ }
+
+ public IEnumerable VisibleRootElements
+ {
+ get
+ {
+ if (SelectedRootElement != null)
+ return new[] { SelectedRootElement };
+ return RootElements;
+ }
+ }
+ }
+}
diff --git a/XSDVisualiser/Models/XsdSchemaModel.cs b/XSDVisualiser/Models/XsdSchemaModel.cs
index 8d4c050..bfd4cb7 100644
--- a/XSDVisualiser/Models/XsdSchemaModel.cs
+++ b/XSDVisualiser/Models/XsdSchemaModel.cs
@@ -54,6 +54,17 @@ namespace XSDVisualiser.Models
[XmlAttribute]
public string? ContentModel { get; set; } // sequence | choice | all | simple
+
+ public override string ToString()
+ {
+ // Used by AutoCompleteBox to get text for filtering and matching
+ // Prefer Name, then TypeName, and fall back to base implementation
+ if (!string.IsNullOrEmpty(Name))
+ return Name!;
+ if (!string.IsNullOrEmpty(TypeName))
+ return TypeName!;
+ return base.ToString();
+ }
}
///