diff --git a/Microsoft.Toolkit.Future/Adorners/AdornerDecorator.cs b/Microsoft.Toolkit.Future/Adorners/AdornerDecorator.cs
deleted file mode 100644
index 8e0cc0a..0000000
--- a/Microsoft.Toolkit.Future/Adorners/AdornerDecorator.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Markup;
-
-namespace CommunityToolkit.WinUI.Controls.Future;
-
-///
-/// Helper class to hold content with an . Use this to wrap another and direct where the should sit. This class is helpful to constrain the or in cases where an appropriate location for the layer can't be automatically determined.
-///
-[TemplatePart(Name = PartAdornerLayer, Type = typeof(AdornerLayer))]
-[ContentProperty(Name = nameof(Child))]
-public sealed class AdornerDecorator : Control
-{
- private const string PartAdornerLayer = "AdornerLayer";
-
- public UIElement Child
- {
- get { return (UIElement)GetValue(ContentProperty); }
- set { SetValue(ContentProperty, value); }
- }
-
- // Using a DependencyProperty as the backing store for Content. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty ContentProperty =
- DependencyProperty.Register(nameof(Child), typeof(UIElement), typeof(AdornerDecorator), new PropertyMetadata(null));
-
- public AdornerLayer? AdornerLayer { get; private set; }
-
- public AdornerDecorator()
- {
- this.DefaultStyleKey = typeof(AdornerDecorator);
- }
-
- protected override void OnApplyTemplate()
- {
- base.OnApplyTemplate();
-
- AdornerLayer = GetTemplateChild(PartAdornerLayer) as AdornerLayer;
- }
-}
\ No newline at end of file
diff --git a/Microsoft.Toolkit.Future/Adorners/AdornerDecorator.xaml b/Microsoft.Toolkit.Future/Adorners/AdornerDecorator.xaml
deleted file mode 100644
index 460ba12..0000000
--- a/Microsoft.Toolkit.Future/Adorners/AdornerDecorator.xaml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Microsoft.Toolkit.Future/Adorners/AdornerLayer.cs b/Microsoft.Toolkit.Future/Adorners/AdornerLayer.cs
deleted file mode 100644
index 056c283..0000000
--- a/Microsoft.Toolkit.Future/Adorners/AdornerLayer.cs
+++ /dev/null
@@ -1,259 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using CommunityToolkit.WinUI.Extensions.Future;
-using System;
-using System.Threading.Tasks;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Media;
-
-namespace CommunityToolkit.WinUI.Controls.Future;
-
-///
-/// An adornment layer which can hold content to show on top of other components. If none is specified, one will be injected into your app content for you.
-///
-public partial class AdornerLayer : Canvas
-{
- public static UIElement GetXaml(FrameworkElement obj)
- {
- return (UIElement)obj.GetValue(XamlProperty);
- }
-
- ///
- /// Sets the of a . Use this to attach any as an adorner to another . Requires that an is available in the visual tree above the adorned element.
- ///
- ///
- ///
- public static void SetXaml(FrameworkElement obj, UIElement value)
- {
- obj.SetValue(XamlProperty, value);
- }
-
- ///
- /// Identifies the Xaml Attached Property.
- ///
- public static readonly DependencyProperty XamlProperty =
- DependencyProperty.RegisterAttached("Xaml", typeof(UIElement), typeof(AdornerLayer), new PropertyMetadata(null, OnXamlPropertyChanged));
-
- public AdornerLayer()
- {
- SizeChanged += AdornerLayer_SizeChanged;
- }
-
- private void AdornerLayer_SizeChanged(object sender, SizeChangedEventArgs e)
- {
- foreach (var adorner in Children)
- {
- if (adorner is Border border && border.Tag is FrameworkElement adornedElement)
- {
- border.Width = adornedElement.ActualWidth;
- border.Height = adornedElement.ActualHeight;
-
- var coord = this.CoordinatesTo(adornedElement);
-
- Canvas.SetLeft(border, coord.X);
- Canvas.SetTop(border, coord.Y);
- }
- }
- }
-
- private static async void OnXamlPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
- {
- if (dependencyObject is FrameworkElement fe)
- {
- if (!fe.IsLoaded || fe.Parent is null)
- {
- fe.Loaded += XamlPropertyFrameworkElement_Loaded;
- }
- else if (args.NewValue is UIElement adorner)
- {
- var layer = await GetAdornerLayerAsync(fe);
-
- if (layer is not null)
- {
- AttachAdorner(layer, fe, adorner);
- }
- }
- else if (args.NewValue == null && args.OldValue is UIElement oldAdorner)
- {
- var layer = await GetAdornerLayerAsync(fe);
-
- if (layer is not null)
- {
- RemoveAdorner(layer, oldAdorner);
- }
- }
- }
- }
-
- private static async void XamlPropertyFrameworkElement_Loaded(object sender, RoutedEventArgs e)
- {
- if (sender is FrameworkElement fe)
- {
- fe.Loaded -= XamlPropertyFrameworkElement_Loaded;
-
- var layer = await GetAdornerLayerAsync(fe);
-
- if (layer is not null)
- {
- var adorner = GetXaml(fe);
-
- if (adorner == null) return;
-
- AttachAdorner(layer, fe, adorner);
- }
- }
- }
-
- ///
- /// Retrieves the closest (or creates an) for the given element. If awaited, the retrieved adorner layer is guaranteed to be loaded. This is to assist adorners with being able to be positioned in relation to the loaded element.
- /// There may be multiple s within an application, as each should have one to enable relational scrolling along content that may be outside of the viewport.
- ///
- /// Element to adorn.
- /// Loaded responsible for that element.
- public static async Task GetAdornerLayerAsync(FrameworkElement adornedElement)
- {
- // 1. Find Adorner Layer for element or top-most element
- FrameworkElement? lastElement = null;
-
- var adornerLayerOrTopMostElement = adornedElement.FindAscendant((element) =>
- {
- lastElement = element; // TODO: should this be after our if, does it matter?
-
- if (element is AdornerDecorator)
- {
- return true;
- }
- else if (element is AdornerLayer)
- {
- return true;
- }
- else if (element is ScrollViewer)
- {
- return true;
- }
- // TODO: Need to figure out porting new DO toolkit helpers to Uno, only needed for custom adorner layer placement...
- /*else
- {
- // TODO: Use BreadthFirst Search w/ Depth Limited?
- var child = element.FindFirstLevelDescendants();
-
- if (child != null)
- {
- lastElement = child;
- return true;
- }
- }*/
-
- return false;
- }) ?? lastElement;
-
- // Check cases where we may have found a child that we want to use instead of the element returned by search.
- if (lastElement is AdornerLayer || lastElement is AdornerDecorator)
- {
- adornerLayerOrTopMostElement = lastElement;
- }
-
- if (adornerLayerOrTopMostElement is AdornerDecorator decorator)
- {
- await decorator.WaitUntilLoadedAsync();
-
- return decorator.AdornerLayer;
- }
- else if (adornerLayerOrTopMostElement is AdornerLayer layer)
- {
- await layer.WaitUntilLoadedAsync();
-
- // If we just have an adorner layer now, we're done!
- return layer;
- }
- else
- {
- // TODO: Windows.UI.Xaml.Internal.RootScrollViewer is a maybe different and what was causing issues before I looked for ScrollViewers along the way?
- // It's an internal unexposed type, so maybe it inherits from ScrollViewer? Not sure yet, but might need to detect and
- // do something different here?
-
- // ScrollViewers need AdornerLayers so they can provide adorners that scroll with the adorned elements (as it worked in WPF).
- // Note: ScrollViewers and the Window were the main AdornerLayer integration points in WPF.
- if (adornerLayerOrTopMostElement is ScrollViewer scroller)
- {
- var content = scroller.Content as FrameworkElement;
-
- // Extra code for RootScrollViewer TODO: Can we detect this better?
- if (scroller.Parent == null)
- {
- //// XamlMarkupHelper.UnloadObject doesn't work here (throws an invalid value exception) does content need a name?
- // TODO: Figure out this scenario?
- throw new NotImplementedException("RootScrollViewer attachment isn't supported, add a AdornerDecorator or ScrollViewer manually to the top-level of your application.");
- }
-
- scroller.Content = null;
-
- var layerContainer = new AdornerDecorator()
- {
- Child = content!,
- };
-
- scroller.Content = layerContainer;
-
- await layerContainer.WaitUntilLoadedAsync();
-
- return layerContainer.AdornerLayer;
- }
- // Grid seems like the easiest place for us to inject AdornerLayers automatically at the top-level (if needed) - not sure how common this will be?
- else if (adornerLayerOrTopMostElement is Grid grid)
- {
- // TODO: Not sure how we want to handle AdornerDecorator in this scenario...
- var adornerLayer = new AdornerLayer();
-
- // TODO: Handle if grid row/columns change.
- Grid.SetRowSpan(adornerLayer, grid.RowDefinitions.Count);
- Grid.SetColumnSpan(adornerLayer, grid.ColumnDefinitions.Count);
- grid.Children.Add(adornerLayer);
-
- await adornerLayer.WaitUntilLoadedAsync();
-
- return adornerLayer;
- }
- }
-
- return null;
- }
-
- // TODO: Temp helper? Build into 'Adorner' base class?
- private static void AttachAdorner(AdornerLayer layer, FrameworkElement adornedElement, UIElement adorner)
- {
- // Add adorner XAML content to the Adorner Layer
-
- var border = new Border()
- {
- Child = adorner,
- Width = adornedElement.ActualWidth, // TODO: Register/tie to size of element better for changes.
- Height = adornedElement.ActualHeight,
- HorizontalAlignment = HorizontalAlignment.Stretch,
- VerticalAlignment = VerticalAlignment.Stretch,
- Tag = adornedElement,
- };
-
- var coord = layer.CoordinatesTo(adornedElement);
-
- Canvas.SetLeft(border, coord.X);
- Canvas.SetTop(border, coord.Y);
-
- layer.Children.Add(border);
- }
-
- private static void RemoveAdorner(AdornerLayer layer, UIElement adorner)
- {
- var border = adorner.FindAscendant();
-
- if (border != null)
- {
- layer.Children.Remove(border);
-
- VisualTreeHelper.DisconnectChildrenRecursive(border);
- }
- }
-}
\ No newline at end of file
diff --git a/Microsoft.Toolkit.Future/Microsoft.Toolkit.Future.csproj b/Microsoft.Toolkit.Future/Microsoft.Toolkit.Future.csproj
index 0182ebb..314d25b 100644
--- a/Microsoft.Toolkit.Future/Microsoft.Toolkit.Future.csproj
+++ b/Microsoft.Toolkit.Future/Microsoft.Toolkit.Future.csproj
@@ -106,8 +106,6 @@
PackageReference
-
-
@@ -145,10 +143,6 @@
-
- Designer
- MSBuild:Compile
-
MSBuild:Compile
Designer
diff --git a/Microsoft.Toolkit.Future/Themes/Generic.xaml b/Microsoft.Toolkit.Future/Themes/Generic.xaml
index cd284c9..33377b1 100644
--- a/Microsoft.Toolkit.Future/Themes/Generic.xaml
+++ b/Microsoft.Toolkit.Future/Themes/Generic.xaml
@@ -1,6 +1,5 @@
-
diff --git a/XamlStudio.Toolkit/Controls/Adorners/AdornerHelpers.cs b/XamlStudio.Toolkit/Controls/Adorners/AdornerHelpers.cs
new file mode 100644
index 0000000..fb3ae49
--- /dev/null
+++ b/XamlStudio.Toolkit/Controls/Adorners/AdornerHelpers.cs
@@ -0,0 +1,16 @@
+using Windows.UI.Xaml;
+
+namespace XamlStudio.Toolkit.Controls.Adorners;
+
+public static class AdornerHelpers
+{
+ public static string GetElementInfo(DependencyObject element)
+ {
+ if (element == null) return "null";
+
+ var name = element.ReadLocalValue(FrameworkElement.NameProperty);
+
+ return ((name != DependencyProperty.UnsetValue) ? $"\"{name}\" " : "") +
+ "<" + element.GetType().Name + ">";
+ }
+}
diff --git a/XamlStudio/Controls/ModifySelectorAdorner.xaml b/XamlStudio.Toolkit/Controls/Adorners/ModifySelectorAdorner.xaml
similarity index 52%
rename from XamlStudio/Controls/ModifySelectorAdorner.xaml
rename to XamlStudio.Toolkit/Controls/Adorners/ModifySelectorAdorner.xaml
index 7459f08..e179d44 100644
--- a/XamlStudio/Controls/ModifySelectorAdorner.xaml
+++ b/XamlStudio.Toolkit/Controls/Adorners/ModifySelectorAdorner.xaml
@@ -1,13 +1,14 @@
-
+
-
-
+
+
-
+
diff --git a/XamlStudio.Toolkit/Controls/Adorners/ModifySelectorAdorner.xaml.cs b/XamlStudio.Toolkit/Controls/Adorners/ModifySelectorAdorner.xaml.cs
new file mode 100644
index 0000000..b23a737
--- /dev/null
+++ b/XamlStudio.Toolkit/Controls/Adorners/ModifySelectorAdorner.xaml.cs
@@ -0,0 +1,57 @@
+using CommunityToolkit.WinUI;
+using System;
+using Windows.Foundation;
+using Windows.UI;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+
+namespace XamlStudio.Toolkit.Controls.Adorners;
+
+public sealed partial class ModifySelectorAdorner : Adorner
+{
+ public event TypedEventHandler SelectedElementClicked;
+
+ public Type AdornedElementType
+ {
+ get { return (Type)GetValue(AdornedElementTypeProperty); }
+ set { SetValue(AdornedElementTypeProperty, value); }
+ }
+
+ public static readonly DependencyProperty AdornedElementTypeProperty =
+ DependencyProperty.Register(nameof(AdornedElementType), typeof(Type), typeof(ModifySelectorAdorner), new PropertyMetadata(null));
+
+ public bool IsContainer
+ {
+ get { return (bool)GetValue(IsContainerProperty); }
+ set { SetValue(IsContainerProperty, value); }
+ }
+
+ public static readonly DependencyProperty IsContainerProperty =
+ DependencyProperty.Register(nameof(IsContainer), typeof(bool), typeof(ModifySelectorAdorner), new PropertyMetadata(null));
+
+ public ModifySelectorAdorner()
+ {
+ this.InitializeComponent();
+ }
+
+ protected override void OnAttached()
+ {
+ base.OnAttached();
+
+ AdornedElementType = AdornedElement.GetType();
+ IsContainer = typeof(Panel).IsAssignableFrom(AdornedElementType) || typeof(ItemsControl).IsAssignableFrom(AdornedElementType);
+ }
+
+ protected override void OnPointerReleased(PointerRoutedEventArgs e)
+ {
+ base.OnPointerReleased(e);
+
+ SelectedElementClicked?.Invoke(this, AdornedElement);
+ }
+
+ public static HorizontalAlignment AlignmentForContainer(bool isContainer) => isContainer ? HorizontalAlignment.Right : HorizontalAlignment.Left;
+
+ public static SolidColorBrush ColorForContainer(bool isContainer) => new(isContainer ? Colors.Purple : Colors.DarkCyan);
+}
diff --git a/XamlStudio/Controls/SurroundingAdorner.xaml b/XamlStudio.Toolkit/Controls/Adorners/SurroundingAdorner.xaml
similarity index 79%
rename from XamlStudio/Controls/SurroundingAdorner.xaml
rename to XamlStudio.Toolkit/Controls/Adorners/SurroundingAdorner.xaml
index 934509a..784c7d4 100644
--- a/XamlStudio/Controls/SurroundingAdorner.xaml
+++ b/XamlStudio.Toolkit/Controls/Adorners/SurroundingAdorner.xaml
@@ -1,13 +1,13 @@
-
+
-
+
diff --git a/XamlStudio/Controls/SurroundingAdorner.xaml.cs b/XamlStudio.Toolkit/Controls/Adorners/SurroundingAdorner.xaml.cs
similarity index 55%
rename from XamlStudio/Controls/SurroundingAdorner.xaml.cs
rename to XamlStudio.Toolkit/Controls/Adorners/SurroundingAdorner.xaml.cs
index 5c85835..f17f76b 100644
--- a/XamlStudio/Controls/SurroundingAdorner.xaml.cs
+++ b/XamlStudio.Toolkit/Controls/Adorners/SurroundingAdorner.xaml.cs
@@ -1,20 +1,19 @@
-using System;
+using CommunityToolkit.WinUI;
+using System;
using System.Reflection;
using Windows.Foundation;
using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-namespace XamlStudio.Controls;
+namespace XamlStudio.Toolkit.Controls.Adorners;
-public sealed partial class SurroundingAdorner : UserControl
+public sealed partial class SurroundingAdorner : Adorner
{
- public FrameworkElement AttachedElement { get; }
+ // TODO: DP?
+ public Type AdornedElementType { get; private set; }
- public Type AttachedElementType;
+ public Point Position { get; private set; }
- public Point Position { get; }
-
- public Size Size;
+ public Size Size { get; private set; }
public Thickness AttachedBorder = new();
@@ -24,10 +23,45 @@ public sealed partial class SurroundingAdorner : UserControl
public Thickness NegativeMargin;
- public SurroundingAdorner(FrameworkElement attachedElement, Point position)
+ private UIElement _parentElement;
+
+ public SurroundingAdorner(UIElement rootElement)
+ {
+ InitializeComponent();
+
+ _parentElement = rootElement;
+
+ // TODO: Could be nice for Adorner in Toolkit to have a callback event for us for when metrics change...
+ SizeChanged += SurroundingAdorner_SizeChanged;
+ LayoutUpdated += SurroundingAdorner_LayoutUpdated;
+ }
+
+ private void SurroundingAdorner_LayoutUpdated(object sender, object e)
{
- AttachedElement = attachedElement;
- AttachedElementType = AttachedElement.GetType();
+ if (AdornedElement is null) return;
+
+ CalculateMetrics();
+ }
+
+ private void SurroundingAdorner_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ if (AdornedElement is null) return;
+
+ CalculateMetrics();
+ }
+
+ protected override void OnAttached()
+ {
+ base.OnAttached();
+
+ CalculateMetrics();
+ }
+
+ private void CalculateMetrics()
+ {
+ AdornedElementType = AdornedElement.GetType();
+
+ var AttachedElement = AdornedElement as FrameworkElement;
// TODO: We want to listen to any changes to these properties to update our calculations and/or use direct Binding/Converters (remember OneWay)
@@ -41,20 +75,22 @@ public SurroundingAdorner(FrameworkElement attachedElement, Point position)
NegativeMargin = new(-mLeft, -mTop, -mRight, -mBottom); // Used to compensate for the auto-applied margin with our adorner.
Size = new(AttachedElement.ActualSize.X + mLeft + mRight, AttachedElement.ActualSize.Y + mTop + mBottom);
+
+ var position = AdornedElement.CoordinatesFrom(_parentElement);
Position = new(position.X - mLeft, position.Y - mTop);
// Then we'll see if we have Borders or Padding as they're specific to certain types of elements
- if (AttachedElementType.GetProperty("BorderThickness") is PropertyInfo border)
+ if (AdornedElementType.GetProperty("BorderThickness") is PropertyInfo border)
{
AttachedBorder = (Thickness)(border.GetValue(AttachedElement) ?? new());
}
- if (AttachedElementType.GetProperty("Padding") is PropertyInfo padding)
+ if (AdornedElementType.GetProperty("Padding") is PropertyInfo padding)
{
AttachedPadding = (Thickness)(padding.GetValue(AttachedElement) ?? new());
}
- // Calculate inner size (margin is already factord into size by framework)
+ // Calculate inner size (margin is already factored into size by framework)
InnerSize = new Size(AttachedElement.ActualSize.X -
AttachedBorder.Left -
AttachedBorder.Right -
@@ -65,18 +101,5 @@ public SurroundingAdorner(FrameworkElement attachedElement, Point position)
AttachedBorder.Bottom -
AttachedPadding.Top -
AttachedPadding.Bottom);
-
- InitializeComponent();
- }
-
- // TODO: Centralize with one from Properties somewhere?
- public static string GetElementInfo(DependencyObject element)
- {
- if (element == null) return "null";
-
- var name = element.ReadLocalValue(FrameworkElement.NameProperty);
-
- return ((name != DependencyProperty.UnsetValue) ? $"\"{name}\" " : "") +
- "<" + element.GetType().Name + ">";
}
}
diff --git a/XamlStudio.Toolkit/XamlStudio.Toolkit.csproj b/XamlStudio.Toolkit/XamlStudio.Toolkit.csproj
index 5a32d47..9704dd8 100644
--- a/XamlStudio.Toolkit/XamlStudio.Toolkit.csproj
+++ b/XamlStudio.Toolkit/XamlStudio.Toolkit.csproj
@@ -107,6 +107,13 @@
PackageReference
+
+
+ ModifySelectorAdorner.xaml
+
+
+ SurroundingAdorner.xaml
+
@@ -146,6 +153,9 @@
1.3.0
+
+ 0.1.251217-build.2433
+
1.2.93
@@ -166,6 +176,14 @@
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
diff --git a/XamlStudio/App.xaml.cs b/XamlStudio/App.xaml.cs
index bda5d03..1830506 100644
--- a/XamlStudio/App.xaml.cs
+++ b/XamlStudio/App.xaml.cs
@@ -126,7 +126,7 @@ private void App_Resuming(object sender, object e)
}
///
- /// Handles the event of an unhandles exception bubbling up all the way to the App instance.
+ /// Handles the event of an unhandled exception bubbling up all the way to the App instance.
///
private void App_UnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
{
diff --git a/XamlStudio/Controls/EditorAdorners/TextBlockEditAdorner.xaml b/XamlStudio/Controls/EditorAdorners/TextBlockEditAdorner.xaml
index 8ed9769..3078569 100644
--- a/XamlStudio/Controls/EditorAdorners/TextBlockEditAdorner.xaml
+++ b/XamlStudio/Controls/EditorAdorners/TextBlockEditAdorner.xaml
@@ -1,18 +1,19 @@
-
+
-
+
@@ -39,4 +40,4 @@
-
+
diff --git a/XamlStudio/Controls/EditorAdorners/TextBlockEditAdorner.xaml.cs b/XamlStudio/Controls/EditorAdorners/TextBlockEditAdorner.xaml.cs
index c0075d1..35e4587 100644
--- a/XamlStudio/Controls/EditorAdorners/TextBlockEditAdorner.xaml.cs
+++ b/XamlStudio/Controls/EditorAdorners/TextBlockEditAdorner.xaml.cs
@@ -1,37 +1,56 @@
using CommunityToolkit.Mvvm.Messaging;
-using CommunityToolkit.WinUI.Controls.Future;
+using CommunityToolkit.WinUI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using XamlStudio.Models;
namespace XamlStudio.Controls;
-public sealed partial class TextBlockEditAdorner : UserControl
+public sealed partial class TextBlockEditAdorner : Adorner
{
- public TextBlock AttachedElement { get; }
-
private string _originalText;
- public TextBlockEditAdorner(FrameworkElement attachedElement)
+ public TextBlock AdornedTextBlock
+ {
+ get { return (TextBlock)GetValue(AdornedTextBlockProperty); }
+ set { SetValue(AdornedTextBlockProperty, value); }
+ }
+
+ public static readonly DependencyProperty AdornedTextBlockProperty =
+ DependencyProperty.Register(nameof(AdornedTextBlock), typeof(TextBlock), typeof(TextBlockEditAdorner), new PropertyMetadata(null));
+
+ public TextBlockEditAdorner()
+ {
+ this.InitializeComponent();
+ }
+
+ protected override void OnAttached()
+ {
+ base.OnAttached();
+
+ AdornedTextBlock = AdornedElement as TextBlock;
+ _originalText = AdornedTextBlock.Text;
+ }
+
+ protected override void OnDetaching()
{
- AttachedElement = attachedElement as TextBlock;
- _originalText = AttachedElement.Text;
+ base.OnDetaching();
- InitializeComponent();
+ AdornedTextBlock = null;
}
private void AcceptButton_Click(object sender, RoutedEventArgs e)
{
- WeakReferenceMessenger.Default.Send(new(AttachedElement, "Text", AttachedElement.Text.Replace("\"", """)));
+ WeakReferenceMessenger.Default.Send(new(AdornedTextBlock, "Text", AdornedTextBlock.Text.Replace("\"", """)));
- AdornerLayer.SetXaml(AttachedElement, null);
+ AdornerLayer.SetXaml(AdornedTextBlock, null);
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
- AdornerLayer.SetXaml(AttachedElement, null);
+ AdornerLayer.SetXaml(AdornedTextBlock, null);
// TODO: We may want to do our trick to check if there's a binding here?
- AttachedElement.Text = _originalText;
+ AdornedTextBlock.Text = _originalText;
}
}
diff --git a/XamlStudio/Controls/ModifySelectorAdorner.xaml.cs b/XamlStudio/Controls/ModifySelectorAdorner.xaml.cs
deleted file mode 100644
index ab3cbe5..0000000
--- a/XamlStudio/Controls/ModifySelectorAdorner.xaml.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using CommunityToolkit.Mvvm.Messaging;
-using System;
-using Windows.UI;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
-using XamlStudio.Models;
-using XamlStudio.ViewModels;
-
-namespace XamlStudio.Controls;
-
-///
-/// Used with Mouse Pointer events to help select an element to modify.
-///
-public sealed partial class ModifySelectorAdorner : UserControl
-{
- public FrameworkElement AttachedElement { get; }
-
- public Type AttachedElementType;
-
- public bool IsContainer => typeof(Panel).IsAssignableFrom(AttachedElementType) || typeof(ItemsControl).IsAssignableFrom(AttachedElementType);
-
- // TODO: Should just make a message type of changing the open activity, maybe a behavior/command bridge for sending message?
- private MainViewModel MainViewModel;
-
- public ModifySelectorAdorner(FrameworkElement attachedElement, MainViewModel mainViewModel)
- {
- AttachedElement = attachedElement;
- AttachedElementType = AttachedElement.GetType();
- MainViewModel = mainViewModel;
-
- this.InitializeComponent();
- }
-
- protected override void OnPointerReleased(PointerRoutedEventArgs e)
- {
- base.OnPointerReleased(e);
-
- if (MainViewModel.OpenActivity != "PROPERTIES")
- {
- MainViewModel.OpenActivityPanelCommand.Execute("PROPERTIES");
- }
- WeakReferenceMessenger.Default.Send(new(AttachedElement));
- }
-
- public static HorizontalAlignment AlignmentForContainer(bool isContainer) => isContainer ? HorizontalAlignment.Right : HorizontalAlignment.Left;
-
- public static SolidColorBrush ColorForContainer(bool isContainer) => new(isContainer ? Colors.Purple : Colors.DarkCyan);
-}
diff --git a/XamlStudio/Styles/Page.xaml b/XamlStudio/Styles/Page.xaml
index e271708..8da1690 100644
--- a/XamlStudio/Styles/Page.xaml
+++ b/XamlStudio/Styles/Page.xaml
@@ -1,7 +1,7 @@
-
+
diff --git a/XamlStudio/Views/Document.Design.xaml.cs b/XamlStudio/Views/Document.Design.xaml.cs
index bd0a3b4..512ff09 100644
--- a/XamlStudio/Views/Document.Design.xaml.cs
+++ b/XamlStudio/Views/Document.Design.xaml.cs
@@ -1,7 +1,6 @@
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.WinUI;
using CommunityToolkit.WinUI.Controls;
-using CommunityToolkit.WinUI.Controls.Future;
using Microsoft.Language.Xml;
using Monaco;
using System;
@@ -15,6 +14,7 @@
using Windows.UI.Xaml.Media;
using XamlStudio.Controls;
using XamlStudio.Models;
+using XamlStudio.Toolkit.Controls.Adorners;
using XamlStudio.Toolkit.Extensions;
namespace XamlStudio.Views;
@@ -52,7 +52,10 @@ private void DesignerModeSelector_SelectionChanged(object sender, SelectionChang
{
foreach (FrameworkElement element in ViewModel.XamlCoordinator.GetVisualElements().Where((e) => e is FrameworkElement))
{
- AdornerLayer.SetXaml(element, new ModifySelectorAdorner(element, ViewModel.MainViewModel));
+ var adorner = new ModifySelectorAdorner();
+ // TODO: Do we just want to weak reference these to not worry about it later?
+ adorner.SelectedElementClicked += Adorner_SelectedElementClicked;
+ AdornerLayer.SetXaml(element, adorner);
}
}
else if (_designerMode != DesignerMode.View)
@@ -61,6 +64,16 @@ private void DesignerModeSelector_SelectionChanged(object sender, SelectionChang
}
}
+ private void Adorner_SelectedElementClicked(ModifySelectorAdorner sender, UIElement adornedElement)
+ {
+ if (ViewModel.MainViewModel.OpenActivity != "PROPERTIES")
+ {
+ ViewModel.MainViewModel.OpenActivityPanelCommand.Execute("PROPERTIES");
+ }
+
+ WeakReferenceMessenger.Default.Send(new(adornedElement));
+ }
+
protected override void OnPointerMoved(PointerRoutedEventArgs e)
{
base.OnPointerMoved(e);
@@ -179,25 +192,27 @@ private void AttachAdorner(FrameworkElement element)
if (_designerMode == DesignerMode.Highlight)
{
- AdornerLayer.SetXaml(ViewModel.HighlightedElement, new SurroundingAdorner(ViewModel.HighlightedElement, ViewModel.HighlightedElement.CoordinatesFrom((UIElement)ViewModel.Result.Element)));
+ AdornerLayer.SetXaml(ViewModel.HighlightedElement, new SurroundingAdorner(ViewModel.Result.Element as UIElement));
}
else if (_designerMode == DesignerMode.Modify)
{
- // TODO: This is the case where we'll have selected something, so we probably want to have a more specific 'editing' adorener here for the specific types of controls
+ // TODO: This is the case where we'll have selected something, so we probably want to have a more specific 'editing' adorner here for the specific types of controls
// e.g for an image it could have a button which opens a file picker for the workspace (or can detect dragged image from there or something)
- // for a textblock it can have a textbox for the contents
+ // for a TextBlock it can have a textbox for the contents
// for a button it can have the behavior for navigation, etc...
if (_editorAdornerTypeMap.TryGetValue(ViewModel.HighlightedElement.GetType(), out var adornerType))
{
// All editor adorners just accept a FrameworkElement
- ConstructorInfo constructor = adornerType.GetConstructor(new[] { typeof(FrameworkElement) });
+ ConstructorInfo constructor = adornerType.GetConstructor(Type.EmptyTypes);
- AdornerLayer.SetXaml(ViewModel.HighlightedElement, constructor.Invoke(new[] { ViewModel.HighlightedElement }) as FrameworkElement);
+ AdornerLayer.SetXaml(ViewModel.HighlightedElement, constructor.Invoke([]) as FrameworkElement);
}
else
{
- AdornerLayer.SetXaml(ViewModel.HighlightedElement, new ModifySelectorAdorner(ViewModel.HighlightedElement, ViewModel.MainViewModel));
+ var adorner = new ModifySelectorAdorner();
+ adorner.SelectedElementClicked += Adorner_SelectedElementClicked;
+ AdornerLayer.SetXaml(ViewModel.HighlightedElement, adorner);
}
}
}
@@ -209,7 +224,12 @@ private void RemoveAdorner()
// Remove all adorners from other elements we had added above for selection
foreach (FrameworkElement element in ViewModel.XamlCoordinator.GetVisualElements().Where((e) => e is FrameworkElement))
{
- AdornerLayer.SetXaml(element, null);
+ var adorner = AdornerLayer.GetXaml(element) as ModifySelectorAdorner;
+ if (adorner is not null)
+ {
+ adorner.SelectedElementClicked -= Adorner_SelectedElementClicked;
+ AdornerLayer.SetXaml(element, null);
+ }
}
}
diff --git a/XamlStudio/Views/Document.xaml b/XamlStudio/Views/Document.xaml
index c73d3e4..52ece78 100644
--- a/XamlStudio/Views/Document.xaml
+++ b/XamlStudio/Views/Document.xaml
@@ -148,7 +148,7 @@
HorizontalScrollBarVisibility="Auto"
HorizontalScrollMode="Auto"
VerticalScrollMode="Auto">
-
+
@@ -163,11 +163,11 @@
-
+
-
+
@@ -182,7 +182,7 @@
-
+
diff --git a/XamlStudio/XamlStudio.csproj b/XamlStudio/XamlStudio.csproj
index 34a3540..eca92ba 100644
--- a/XamlStudio/XamlStudio.csproj
+++ b/XamlStudio/XamlStudio.csproj
@@ -185,12 +185,6 @@
TextBlockEditAdorner.xaml
-
- ModifySelectorAdorner.xaml
-
-
- SurroundingAdorner.xaml
-
DummyPage.xaml
@@ -280,16 +274,8 @@
- Designer
- MSBuild:Compile
-
-
- Designer
MSBuild:Compile
-
-
Designer
- MSBuild:Compile
Designer