A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

175 lines
6.3 KiB

using System;
using System.Text;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Automation.Peers;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using global::Avalonia.Styling;
using AvApplication = global::Avalonia.Application;
namespace WinUIEmbedSample
{
public sealed partial class MainWindow : Microsoft.UI.Xaml.Window
{
private int _clicks;
public MainWindow()
{
InitializeComponent();
App.Lifetime.MainView = new EmbeddedView();
AvaloniaPanel.Content = App.Lifetime.MainView;
// Probe the automation peer *before* the panel is loaded — answers the
// open question of whether GetChildren() works before _root.Prepare().
AppendDiagnostic("ctor: " + DescribePeer());
AvaloniaPanel.Loading += (_, _) => AppendDiagnostic("Loading: " + DescribePeer());
AvaloniaPanel.Loaded += (_, _) =>
{
AppendDiagnostic("Loaded: " + DescribePeer());
};
}
private string DescribePeer()
{
try
{
var peer = FrameworkElementAutomationPeer.CreatePeerForElement(AvaloniaPanel);
if (peer is null)
return "peer=null";
var children = peer.GetChildren();
var count = children?.Count ?? 0;
var sb = new StringBuilder();
sb.Append("peer=").Append(peer.GetType().Name)
.Append(" class=").Append(peer.GetClassName())
.Append(" childCount=").Append(count);
if (count > 0)
{
sb.Append(" first=[");
var first = children![0];
sb.Append(first.GetClassName()).Append('/').Append(first.GetAutomationControlType());
sb.Append("] firstChildren=").Append(first.GetChildren()?.Count ?? 0);
}
return sb.ToString();
}
catch (Exception ex)
{
return "threw: " + ex.GetType().Name + ": " + ex.Message;
}
}
private void ProbePeerButton_Click(object sender, RoutedEventArgs e)
{
AppendDiagnostic("Probe: " + DescribePeer());
}
private async void ProbeWorkerButton_Click(object sender, RoutedEventArgs e)
{
// Cache the peer on the UI thread (CreatePeerForElement is UI-thread bound).
var peer = FrameworkElementAutomationPeer.CreatePeerForElement(AvaloniaPanel);
// Walk on a worker thread — mimics how UIA queries (it calls from a separate thread).
var result = await System.Threading.Tasks.Task.Run(() =>
{
var sb = new StringBuilder();
sb.Append("Worker-thread walk (TID=").Append(Environment.CurrentManagedThreadId).Append("):\n");
try { WalkPeer(peer, 0, sb, maxDepth: 20); }
catch (Exception ex) { sb.Append("THREW: ").Append(ex); }
return sb.ToString();
});
AppendDiagnostic(result);
}
private void ProbeDeepButton_Click(object sender, RoutedEventArgs e)
{
try
{
var peer = FrameworkElementAutomationPeer.CreatePeerForElement(AvaloniaPanel);
var sb = new StringBuilder();
sb.Append("Deep walk:\n");
WalkPeer(peer, 0, sb, maxDepth: 20);
AppendDiagnostic(sb.ToString());
}
catch (Exception ex)
{
AppendDiagnostic("Deep probe threw: " + ex.Message);
}
}
private static void WalkPeer(AutomationPeer peer, int depth, StringBuilder sb, int maxDepth)
{
if (peer is null || depth > maxDepth)
return;
for (var i = 0; i < depth; i++) sb.Append(" ");
var className = peer.GetClassName();
var name = peer.GetName();
var type = peer.GetAutomationControlType();
var children = peer.GetChildren();
sb.Append('[').Append(className).Append(']')
.Append(" type=").Append(type)
.Append(" name=\"").Append(name).Append('"')
.Append(" children=").Append(children?.Count ?? 0)
.Append('\n');
if (children is null) return;
foreach (var child in children)
WalkPeer(child, depth + 1, sb, maxDepth);
}
private void AppendDiagnostic(string line)
{
if (DiagnosticsLog is null)
return;
DiagnosticsLog.Text += "[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + line + "\n";
}
private void WinUiButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
WinUiClickCount.Text = $"Clicked {++_clicks} times";
}
private void WinUiDragSource_DragStarting(
Microsoft.UI.Xaml.UIElement sender,
Microsoft.UI.Xaml.DragStartingEventArgs e)
{
e.Data.SetText("Hello from WinUI");
e.AllowedOperations =
Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy |
Windows.ApplicationModel.DataTransfer.DataPackageOperation.Move;
}
private void WinUiSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
if (WinUiSliderValue is not null)
WinUiSliderValue.Text = $"Slider: {e.NewValue:F0}";
}
private void WinUiThemeCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selected = WinUiThemeCombo.SelectedIndex;
if (Content is FrameworkElement root)
{
root.RequestedTheme = selected switch
{
0 => ElementTheme.Light,
1 => ElementTheme.Dark,
_ => ElementTheme.Default
};
}
if (AvApplication.Current is { } avApp)
{
avApp.RequestedThemeVariant = selected switch
{
0 => ThemeVariant.Light,
1 => ThemeVariant.Dark,
_ => ThemeVariant.Default
};
}
}
}
}