diff --git a/XSDVisualiser.Core/XSDVisualiser.Core.csproj b/XSDVisualiser.Core/XSDVisualiser.Core.csproj
index 180cfa3..980dfd8 100644
--- a/XSDVisualiser.Core/XSDVisualiser.Core.csproj
+++ b/XSDVisualiser.Core/XSDVisualiser.Core.csproj
@@ -1,12 +1,12 @@
-
- net9.0
- enable
- enable
-
-
-
-
-
-
+
+ net9.0
+ enable
+ enable
+
+
+
+
+
+
diff --git a/XSDVisualiser.Desktop/App.axaml b/XSDVisualiser.Desktop/App.axaml
index 059c864..8e03f38 100644
--- a/XSDVisualiser.Desktop/App.axaml
+++ b/XSDVisualiser.Desktop/App.axaml
@@ -4,32 +4,32 @@
xmlns:conv="clr-namespace:XSDVisualiser.Desktop.Converters"
x:Class="XSDVisualiser.Desktop.App"
RequestedThemeVariant="Light">
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/XSDVisualiser.Desktop/App.axaml.cs b/XSDVisualiser.Desktop/App.axaml.cs
index be0ef03..ec7d599 100644
--- a/XSDVisualiser.Desktop/App.axaml.cs
+++ b/XSDVisualiser.Desktop/App.axaml.cs
@@ -2,22 +2,19 @@ using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
-namespace XSDVisualiser.Desktop
-{
- public partial class App : Application
- {
- public override void Initialize()
- {
- AvaloniaXamlLoader.Load(this);
- }
+namespace XSDVisualiser.Desktop;
- public override void OnFrameworkInitializationCompleted()
- {
- if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
- {
- desktop.MainWindow = new MainWindow();
- }
- base.OnFrameworkInitializationCompleted();
- }
+public class App : Application
+{
+ public override void Initialize()
+ {
+ AvaloniaXamlLoader.Load(this);
}
-}
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ desktop.MainWindow = new MainWindow();
+ base.OnFrameworkInitializationCompleted();
+ }
+}
\ No newline at end of file
diff --git a/XSDVisualiser.Desktop/Converters/CardinalityToLabelConverter.cs b/XSDVisualiser.Desktop/Converters/CardinalityToLabelConverter.cs
index de2ebe9..cab0426 100644
--- a/XSDVisualiser.Desktop/Converters/CardinalityToLabelConverter.cs
+++ b/XSDVisualiser.Desktop/Converters/CardinalityToLabelConverter.cs
@@ -1,22 +1,22 @@
-using System;
using System.Globalization;
using Avalonia.Data.Converters;
-using XSDVisualiser.Models;
+using XSDVisualiser.Core;
-namespace XSDVisualiser.Desktop.Converters
+namespace XSDVisualiser.Desktop.Converters;
+
+public class CardinalityToLabelConverter : IValueConverter
{
- public class CardinalityToLabelConverter : IValueConverter
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
- public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- if (value is not Occurs occ) return null;
-
- var min = occ.Min;
- var max = occ.MaxIsUnbounded ? "*" : occ.Max.ToString(culture);
- return $"[{min}..{max}]";
- }
+ if (value is not Occurs occ) return null;
- public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
- => throw new NotSupportedException();
+ var min = occ.Min;
+ var max = occ.MaxIsUnbounded ? "*" : occ.Max.ToString(culture);
+ return $"[{min}..{max}]";
}
-}
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ throw new NotSupportedException();
+ }
+}
\ No newline at end of file
diff --git a/XSDVisualiser.Desktop/Converters/CollectionHasItemsConverter.cs b/XSDVisualiser.Desktop/Converters/CollectionHasItemsConverter.cs
index 48a53c7..e9ff18f 100644
--- a/XSDVisualiser.Desktop/Converters/CollectionHasItemsConverter.cs
+++ b/XSDVisualiser.Desktop/Converters/CollectionHasItemsConverter.cs
@@ -1,37 +1,37 @@
-using System;
using System.Collections;
using System.Globalization;
using Avalonia.Data.Converters;
-namespace XSDVisualiser.Desktop.Converters
-{
- ///
- /// Returns true if the bound value is a collection with at least one item. Supports IEnumerable and ICollection.
- /// Optional parameter "Invert" to invert the boolean result.
- ///
- public sealed class CollectionHasItemsConverter : IValueConverter
- {
- public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- var hasItems = false;
- switch (value)
- {
- case ICollection coll:
- hasItems = coll.Count > 0;
- break;
- case IEnumerable enumerable:
- {
- var enumerator = enumerable.GetEnumerator();
- hasItems = enumerator.MoveNext();
- break;
- }
- }
+namespace XSDVisualiser.Desktop.Converters;
- var invert = parameter is string s && s.Equals("Invert", StringComparison.OrdinalIgnoreCase);
- return invert ? !hasItems : hasItems;
+///
+/// Returns true if the bound value is a collection with at least one item. Supports IEnumerable and ICollection.
+/// Optional parameter "Invert" to invert the boolean result.
+///
+public sealed class CollectionHasItemsConverter : IValueConverter
+{
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ var hasItems = false;
+ switch (value)
+ {
+ case ICollection coll:
+ hasItems = coll.Count > 0;
+ break;
+ case IEnumerable enumerable:
+ {
+ var enumerator = enumerable.GetEnumerator();
+ hasItems = enumerator.MoveNext();
+ break;
+ }
}
- public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
- => throw new NotSupportedException();
+ var invert = parameter is string s && s.Equals("Invert", StringComparison.OrdinalIgnoreCase);
+ return invert ? !hasItems : hasItems;
}
-}
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ throw new NotSupportedException();
+ }
+}
\ No newline at end of file
diff --git a/XSDVisualiser.Desktop/Converters/OptionalToBorderBrushConverter.cs b/XSDVisualiser.Desktop/Converters/OptionalToBorderBrushConverter.cs
index 8fef8b7..d437a32 100644
--- a/XSDVisualiser.Desktop/Converters/OptionalToBorderBrushConverter.cs
+++ b/XSDVisualiser.Desktop/Converters/OptionalToBorderBrushConverter.cs
@@ -1,27 +1,25 @@
-using System;
using System.Globalization;
using Avalonia.Data.Converters;
using Avalonia.Media;
-using XSDVisualiser.Models;
+using XSDVisualiser.Core;
-namespace XSDVisualiser.Desktop.Converters
+namespace XSDVisualiser.Desktop.Converters;
+
+public class OptionalToBorderBrushConverter : IValueConverter
{
- public class OptionalToBorderBrushConverter : IValueConverter
+ private static readonly IBrush RequiredBrush = new SolidColorBrush(Color.FromRgb(0x33, 0x99, 0x33));
+ private static readonly IBrush OptionalBrush = new SolidColorBrush(Color.FromRgb(0xCC, 0x66, 0x33));
+
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
- private static readonly IBrush RequiredBrush = new SolidColorBrush(Color.FromRgb(0x33, 0x99, 0x33));
- private static readonly IBrush OptionalBrush = new SolidColorBrush(Color.FromRgb(0xCC, 0x66, 0x33));
-
- public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- if (value is Occurs occ)
- {
- // Optional if minOccurs == 0
- return occ.Min == 0 ? OptionalBrush : RequiredBrush;
- }
- return RequiredBrush;
- }
-
- public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
- => throw new NotSupportedException();
+ if (value is Occurs occ)
+ // Optional if minOccurs == 0
+ return occ.Min == 0 ? OptionalBrush : RequiredBrush;
+ return RequiredBrush;
}
-}
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ throw new NotSupportedException();
+ }
+}
\ No newline at end of file
diff --git a/XSDVisualiser.Desktop/Converters/OptionalToThicknessConverter.cs b/XSDVisualiser.Desktop/Converters/OptionalToThicknessConverter.cs
index 6145c90..715299e 100644
--- a/XSDVisualiser.Desktop/Converters/OptionalToThicknessConverter.cs
+++ b/XSDVisualiser.Desktop/Converters/OptionalToThicknessConverter.cs
@@ -1,27 +1,25 @@
-using System;
using System.Globalization;
using Avalonia;
using Avalonia.Data.Converters;
-using XSDVisualiser.Models;
+using XSDVisualiser.Core;
-namespace XSDVisualiser.Desktop.Converters
+namespace XSDVisualiser.Desktop.Converters;
+
+public class OptionalToThicknessConverter : IValueConverter
{
- public class OptionalToThicknessConverter : IValueConverter
+ private static readonly Thickness Required = new(2);
+ private static readonly Thickness Optional = new(2);
+
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
- private static readonly Thickness Required = new Thickness(2);
- private static readonly Thickness Optional = new Thickness(2);
-
- public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- if (value is Occurs occ)
- {
- // We could vary thickness; for now same thickness regardless, reserved for future styling.
- return occ.Min == 0 ? Optional : Required;
- }
- return Required;
- }
-
- public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
- => throw new NotSupportedException();
+ if (value is Occurs occ)
+ // We could vary thickness; for now same thickness regardless, reserved for future styling.
+ return occ.Min == 0 ? Optional : Required;
+ return Required;
}
-}
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ throw new NotSupportedException();
+ }
+}
\ No newline at end of file
diff --git a/XSDVisualiser.Desktop/MainWindow.axaml b/XSDVisualiser.Desktop/MainWindow.axaml
index 0d25244..cc978ca 100644
--- a/XSDVisualiser.Desktop/MainWindow.axaml
+++ b/XSDVisualiser.Desktop/MainWindow.axaml
@@ -7,11 +7,12 @@
-
+
-
+
-
+
\ No newline at end of file
diff --git a/XSDVisualiser.Desktop/MainWindow.axaml.cs b/XSDVisualiser.Desktop/MainWindow.axaml.cs
index aad28b6..f0b5a98 100644
--- a/XSDVisualiser.Desktop/MainWindow.axaml.cs
+++ b/XSDVisualiser.Desktop/MainWindow.axaml.cs
@@ -1,12 +1,11 @@
using Avalonia.Controls;
-namespace XSDVisualiser.Desktop
+namespace XSDVisualiser.Desktop;
+
+public partial class MainWindow : Window
{
- public partial class MainWindow : Window
+ public MainWindow()
{
- public MainWindow()
- {
- InitializeComponent();
- }
+ InitializeComponent();
}
-}
+}
\ No newline at end of file
diff --git a/XSDVisualiser.Desktop/Program.cs b/XSDVisualiser.Desktop/Program.cs
index 41f59e6..5b84921 100644
--- a/XSDVisualiser.Desktop/Program.cs
+++ b/XSDVisualiser.Desktop/Program.cs
@@ -1,21 +1,21 @@
-using System;
using Avalonia;
using Avalonia.ReactiveUI;
-namespace XSDVisualiser.Desktop
-{
- internal static class Program
- {
- [STAThread]
- public static void Main(string[] args)
- {
- BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
- }
+namespace XSDVisualiser.Desktop;
- private static AppBuilder BuildAvaloniaApp() =>
- AppBuilder.Configure()
- .UsePlatformDetect()
- .LogToTrace()
- .UseReactiveUI();
+internal static class Program
+{
+ [STAThread]
+ public static void Main(string[] args)
+ {
+ BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
-}
+
+ private static AppBuilder BuildAvaloniaApp()
+ {
+ return AppBuilder.Configure()
+ .UsePlatformDetect()
+ .LogToTrace()
+ .UseReactiveUI();
+ }
+}
\ No newline at end of file
diff --git a/XSDVisualiser.Desktop/ViewModels/MainWindowViewModel.cs b/XSDVisualiser.Desktop/ViewModels/MainWindowViewModel.cs
index d85b13d..7b24482 100644
--- a/XSDVisualiser.Desktop/ViewModels/MainWindowViewModel.cs
+++ b/XSDVisualiser.Desktop/ViewModels/MainWindowViewModel.cs
@@ -1,80 +1,80 @@
-using System;
-using System.Collections.Generic;
using System.ComponentModel;
-using System.Linq;
using System.Runtime.CompilerServices;
-using XSDVisualiser.Models;
+using XSDVisualiser.Core;
-namespace XSDVisualiser.Desktop.ViewModels
+namespace XSDVisualiser.Desktop.ViewModels;
+
+public class MainWindowViewModel(SchemaModel model) : INotifyPropertyChanged
{
- public class MainWindowViewModel(SchemaModel model) : INotifyPropertyChanged
+ private string? _currentFilePath;
+ private SchemaModel _model = model ?? throw new ArgumentNullException(nameof(model));
+ private SchemaNode? _selectedNode;
+ private SchemaNode? _selectedRootElement;
+
+ public SchemaModel Model
{
- private SchemaModel _model = model ?? throw new ArgumentNullException(nameof(model));
- private SchemaNode? _selectedRootElement;
- private SchemaNode? _selectedNode;
-
- public event PropertyChangedEventHandler? PropertyChanged;
-
- private void OnPropertyChanged([CallerMemberName] string? name = null)
+ get => _model;
+ set
{
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ if (ReferenceEquals(_model, value)) return;
+ _model = value ?? throw new ArgumentNullException(nameof(value));
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(RootElements));
+ OnPropertyChanged(nameof(VisibleRootElements));
}
-
- public SchemaModel Model
- {
- get => _model;
- set
- {
- if (ReferenceEquals(_model, value)) return;
- _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)) return;
- _selectedRootElement = value;
- OnPropertyChanged();
- OnPropertyChanged(nameof(VisibleRootElements));
- }
- }
-
- public SchemaNode? SelectedNode
- {
- get => _selectedNode;
- set
- {
- if (EqualityComparer.Default.Equals(_selectedNode, value)) return;
- _selectedNode = value;
- OnPropertyChanged();
- }
- }
-
- public IEnumerable VisibleRootElements => SelectedRootElement != null ? [SelectedRootElement] : RootElements;
-
- private string? _currentFilePath;
- public string? CurrentFilePath
- {
- get => _currentFilePath;
- set
- {
- if (string.Equals(_currentFilePath, value, StringComparison.Ordinal)) return;
- _currentFilePath = value;
- OnPropertyChanged();
- OnPropertyChanged(nameof(CurrentFileName));
- OnPropertyChanged(nameof(CurrentDirectory));
- }
- }
-
- public string? CurrentFileName => string.IsNullOrEmpty(_currentFilePath) ? null : System.IO.Path.GetFileName(_currentFilePath);
- public string? CurrentDirectory => string.IsNullOrEmpty(_currentFilePath) ? null : System.IO.Path.GetDirectoryName(_currentFilePath);
}
-}
+
+ public IEnumerable RootElements => _model?.RootElements ?? Enumerable.Empty();
+
+ public SchemaNode? SelectedRootElement
+ {
+ get => _selectedRootElement;
+ set
+ {
+ if (EqualityComparer.Default.Equals(_selectedRootElement, value)) return;
+ _selectedRootElement = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(VisibleRootElements));
+ }
+ }
+
+ public SchemaNode? SelectedNode
+ {
+ get => _selectedNode;
+ set
+ {
+ if (EqualityComparer.Default.Equals(_selectedNode, value)) return;
+ _selectedNode = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public IEnumerable VisibleRootElements =>
+ SelectedRootElement != null ? [SelectedRootElement] : RootElements;
+
+ public string? CurrentFilePath
+ {
+ get => _currentFilePath;
+ set
+ {
+ if (string.Equals(_currentFilePath, value, StringComparison.Ordinal)) return;
+ _currentFilePath = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(CurrentFileName));
+ OnPropertyChanged(nameof(CurrentDirectory));
+ }
+ }
+
+ public string? CurrentFileName =>
+ string.IsNullOrEmpty(_currentFilePath) ? null : Path.GetFileName(_currentFilePath);
+
+ public string? CurrentDirectory =>
+ string.IsNullOrEmpty(_currentFilePath) ? null : Path.GetDirectoryName(_currentFilePath);
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ private void OnPropertyChanged([CallerMemberName] string? name = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+}
\ No newline at end of file
diff --git a/XSDVisualiser.Desktop/Views/HeaderView.axaml b/XSDVisualiser.Desktop/Views/HeaderView.axaml
index 81842a7..0b9d634 100644
--- a/XSDVisualiser.Desktop/Views/HeaderView.axaml
+++ b/XSDVisualiser.Desktop/Views/HeaderView.axaml
@@ -8,23 +8,23 @@
FontSize="20"
FontWeight="SemiBold"
Margin="0,0,12,0"
- VerticalAlignment="Center"/>
+ VerticalAlignment="Center" />
+ Margin="0,0,12,0"
+ Watermark="Search and choose a root element"
+ ItemsSource="{Binding RootElements}"
+ FilterMode="Contains"
+ MinimumPrefixLength="0"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Center">
-
+
-
+
@@ -32,7 +32,7 @@
Content="Open XSD and parse"
x:Name="OpenBtn"
Width="220"
- VerticalAlignment="Center"/>
+ VerticalAlignment="Center" />
-
-
+
+
-
+
-
-
+
+
-
+
\ No newline at end of file
diff --git a/XSDVisualiser.Desktop/Views/HeaderView.axaml.cs b/XSDVisualiser.Desktop/Views/HeaderView.axaml.cs
index 67e7b3a..d61d5b9 100644
--- a/XSDVisualiser.Desktop/Views/HeaderView.axaml.cs
+++ b/XSDVisualiser.Desktop/Views/HeaderView.axaml.cs
@@ -1,12 +1,9 @@
-using System;
-using System.Threading.Tasks;
-using Avalonia;
+using System.Diagnostics;
using Avalonia.Controls;
using Avalonia.Interactivity;
-using Avalonia.Threading;
using Avalonia.Platform.Storage;
+using Avalonia.Threading;
using XSDVisualiser.Core;
-using XSDVisualiser.Models;
using XSDVisualiser.Desktop.ViewModels;
namespace XSDVisualiser.Desktop.Views;
@@ -19,10 +16,7 @@ public partial class HeaderView : UserControl
{
InitializeComponent();
_openBtn = this.FindControl