diff --git a/src/Avalonia.Diagnostics/DevTools.xaml b/src/Avalonia.Diagnostics/DevTools.xaml
index 0f55d42e33..a538516c1a 100644
--- a/src/Avalonia.Diagnostics/DevTools.xaml
+++ b/src/Avalonia.Diagnostics/DevTools.xaml
@@ -1,23 +1,24 @@
-
-
-
-
-
-
+
-
-
-
- Hold Ctrl+Shift over a control to inspect.
-
- Focused:
-
-
- Pointer Over:
-
-
-
+
+
+
+
+
+
+
+
+
+ Hold Ctrl+Shift over a control to inspect.
+
+ Focused:
+
+
+ Pointer Over:
+
+
+
diff --git a/src/Avalonia.Diagnostics/DevTools.xaml.cs b/src/Avalonia.Diagnostics/DevTools.xaml.cs
index e0bacf326b..ccb6151ada 100644
--- a/src/Avalonia.Diagnostics/DevTools.xaml.cs
+++ b/src/Avalonia.Diagnostics/DevTools.xaml.cs
@@ -1,10 +1,13 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
-using Avalonia.Controls.Templates;
using Avalonia.Diagnostics.ViewModels;
using Avalonia.Input;
using Avalonia.Input.Raw;
@@ -82,7 +85,8 @@ namespace Avalonia.Diagnostics
DataTemplates =
{
new ViewLocator(),
- }
+ },
+ Title = "Avalonia DevTools"
};
devToolsWindow.Closed += devTools.DevToolsClosed;
diff --git a/src/Avalonia.Diagnostics/ViewLocator.cs b/src/Avalonia.Diagnostics/ViewLocator.cs
index b107338aec..cda511909a 100644
--- a/src/Avalonia.Diagnostics/ViewLocator.cs
+++ b/src/Avalonia.Diagnostics/ViewLocator.cs
@@ -31,4 +31,4 @@ namespace Avalonia.Diagnostics
return data is TViewModel;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs
index c6d3f02e8b..bc80ab0550 100644
--- a/src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs
+++ b/src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs
@@ -2,7 +2,9 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
-using System.Reactive.Linq;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
using Avalonia.Controls;
using Avalonia.Input;
@@ -10,21 +12,23 @@ namespace Avalonia.Diagnostics.ViewModels
{
internal class DevToolsViewModel : ViewModelBase
{
- private ViewModelBase _content;
- private int _selectedTab;
- private TreePageViewModel _logicalTree;
- private TreePageViewModel _visualTree;
- private EventsViewModel _eventsView;
+ private IDevToolViewModel _selectedTool;
private string _focusedControl;
private string _pointerOverElement;
public DevToolsViewModel(IControl root)
{
- _logicalTree = new TreePageViewModel(LogicalTreeNode.Create(root));
- _visualTree = new TreePageViewModel(VisualTreeNode.Create(root));
- _eventsView = new EventsViewModel(root);
+ Tools = new ObservableCollection
+ {
+ new TreePageViewModel(LogicalTreeNode.Create(root), "Logical Tree"),
+ new TreePageViewModel(VisualTreeNode.Create(root), "Visual Tree"),
+ new EventsViewModel(root)
+ };
+
+ SelectedTool = Tools.First();
UpdateFocusedControl();
+
KeyboardDevice.Instance.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(KeyboardDevice.Instance.FocusedElement))
@@ -33,58 +37,33 @@ namespace Avalonia.Diagnostics.ViewModels
}
};
- SelectedTab = 0;
root.GetObservable(TopLevel.PointerOverElementProperty)
.Subscribe(x => PointerOverElement = x?.GetType().Name);
}
- public ViewModelBase Content
+ public IDevToolViewModel SelectedTool
{
- get { return _content; }
- private set { RaiseAndSetIfChanged(ref _content, value); }
+ get => _selectedTool;
+ set => RaiseAndSetIfChanged(ref _selectedTool, value);
}
- public int SelectedTab
- {
- get { return _selectedTab; }
- set
- {
- _selectedTab = value;
-
- switch (value)
- {
- case 0:
- Content = _logicalTree;
- break;
- case 1:
- Content = _visualTree;
- break;
- case 2:
- Content = _eventsView;
- break;
- }
-
- RaisePropertyChanged();
- }
- }
+ public ObservableCollection Tools { get; }
public string FocusedControl
{
- get { return _focusedControl; }
- private set { RaiseAndSetIfChanged(ref _focusedControl, value); }
+ get => _focusedControl;
+ private set => RaiseAndSetIfChanged(ref _focusedControl, value);
}
public string PointerOverElement
{
- get { return _pointerOverElement; }
- private set { RaiseAndSetIfChanged(ref _pointerOverElement, value); }
+ get => _pointerOverElement;
+ private set => RaiseAndSetIfChanged(ref _pointerOverElement, value);
}
public void SelectControl(IControl control)
{
- var tree = Content as TreePageViewModel;
-
- if (tree != null)
+ if (SelectedTool is TreePageViewModel tree)
{
tree.SelectControl(control);
}
diff --git a/src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs
index a23677afc8..1c868148ce 100644
--- a/src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs
+++ b/src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs
@@ -5,8 +5,6 @@ using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
-using System.Windows.Input;
-
using Avalonia.Controls;
using Avalonia.Data.Converters;
using Avalonia.Interactivity;
@@ -14,21 +12,24 @@ using Avalonia.Media;
namespace Avalonia.Diagnostics.ViewModels
{
- internal class EventsViewModel : ViewModelBase
+ internal class EventsViewModel : ViewModelBase, IDevToolViewModel
{
private readonly IControl _root;
private FiredEvent _selectedEvent;
public EventsViewModel(IControl root)
{
- this._root = root;
- this.Nodes = RoutedEventRegistry.Instance.GetAllRegistered()
+ _root = root;
+
+ Nodes = RoutedEventRegistry.Instance.GetAllRegistered()
.GroupBy(e => e.OwnerType)
.OrderBy(e => e.Key.Name)
.Select(g => new EventOwnerTreeNode(g.Key, g, this))
.ToArray();
}
+ public string Name => "Events";
+
public EventTreeNodeBase[] Nodes { get; }
public ObservableCollection RecordedEvents { get; } = new ObservableCollection();
@@ -49,7 +50,7 @@ namespace Avalonia.Diagnostics.ViewModels
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
- return (bool)value ? Brushes.LightGreen : Brushes.Transparent;
+ return (bool)value ? Brushes.Green : Brushes.Transparent;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
diff --git a/src/Avalonia.Diagnostics/ViewModels/IDevToolViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/IDevToolViewModel.cs
new file mode 100644
index 0000000000..0434230a63
--- /dev/null
+++ b/src/Avalonia.Diagnostics/ViewModels/IDevToolViewModel.cs
@@ -0,0 +1,16 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+namespace Avalonia.Diagnostics.ViewModels
+{
+ ///
+ /// View model interface for tool showing up in DevTools
+ ///
+ public interface IDevToolViewModel
+ {
+ ///
+ /// Name of a tool.
+ ///
+ string Name { get; }
+ }
+}
diff --git a/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs
index dba44c5d0c..6b294c98bd 100644
--- a/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs
+++ b/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs
@@ -6,16 +6,19 @@ using Avalonia.VisualTree;
namespace Avalonia.Diagnostics.ViewModels
{
- internal class TreePageViewModel : ViewModelBase
+ internal class TreePageViewModel : ViewModelBase, IDevToolViewModel
{
private TreeNode _selected;
private ControlDetailsViewModel _details;
- public TreePageViewModel(TreeNode[] nodes)
+ public TreePageViewModel(TreeNode[] nodes, string name)
{
Nodes = nodes;
+ Name = name;
}
+ public string Name { get; }
+
public TreeNode[] Nodes { get; protected set; }
public TreeNode SelectedNode
diff --git a/src/Avalonia.Diagnostics/Views/ControlDetailsView.cs b/src/Avalonia.Diagnostics/Views/ControlDetailsView.cs
index 381b2e04b4..868bc774bb 100644
--- a/src/Avalonia.Diagnostics/Views/ControlDetailsView.cs
+++ b/src/Avalonia.Diagnostics/Views/ControlDetailsView.cs
@@ -7,7 +7,6 @@ using System.Reactive.Linq;
using Avalonia.Controls;
using Avalonia.Diagnostics.ViewModels;
using Avalonia.Media;
-using Avalonia.Styling;
namespace Avalonia.Diagnostics.Views
{
@@ -42,16 +41,6 @@ namespace Avalonia.Diagnostics.Views
{
Content = _grid = new SimpleGrid
{
- Styles =
- {
- new Style(x => x.Is())
- {
- Setters = new[]
- {
- new Setter(MarginProperty, new Thickness(2)),
- }
- },
- },
[GridRepeater.TemplateProperty] = pt,
}
};
@@ -61,8 +50,11 @@ namespace Avalonia.Diagnostics.Views
{
var property = (PropertyDetails)i;
+ var margin = new Thickness(2);
+
yield return new TextBlock
{
+ Margin = margin,
Text = property.Name,
TextWrapping = TextWrapping.NoWrap,
[!ToolTip.TipProperty] = property.GetObservable(nameof(property.Diagnostic)).ToBinding(),
@@ -70,6 +62,7 @@ namespace Avalonia.Diagnostics.Views
yield return new TextBlock
{
+ Margin = margin,
TextWrapping = TextWrapping.NoWrap,
[!TextBlock.TextProperty] = property.GetObservable