| File: VisualDiagnostics\VisualDiagnostics.cs | Web Access |
| Project: src\src\Core\src\Core.csproj (Microsoft.Maui) |
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; using System.ComponentModel; using System.IO; using System.Runtime.CompilerServices; using System.Threading.Tasks; using Microsoft.Maui.Media; namespace Microsoft.Maui { public static class VisualDiagnostics { static ConditionalWeakTable<object, SourceInfo> sourceInfos = new ConditionalWeakTable<object, SourceInfo>(); static Lazy<bool> isVisualDiagnosticsEnvVarSet = new Lazy<bool>(() => Environment.GetEnvironmentVariable("ENABLE_XAML_DIAGNOSTICS_SOURCE_INFO") is { } value && value == "1"); static internal bool IsEnabled => DebuggerHelper.DebuggerIsAttached || isVisualDiagnosticsEnvVarSet.Value; /// <include file="../../docs/Microsoft.Maui/VisualDiagnostics.xml" path="//Member[@MemberName='RegisterSourceInfo']/Docs/*" /> [EditorBrowsable(EditorBrowsableState.Never)] public static void RegisterSourceInfo(object target, Uri uri, int lineNumber, int linePosition) { #if !NETSTANDARD2_0 if (target != null && VisualDiagnostics.IsEnabled) sourceInfos.AddOrUpdate(target, new SourceInfo(uri, lineNumber, linePosition)); #else if (target != null && VisualDiagnostics.IsEnabled) { if (sourceInfos.TryGetValue(target, out _)) sourceInfos.Remove(target); sourceInfos.Add(target, new SourceInfo(uri, lineNumber, linePosition)); } #endif } /// <include file="../../docs/Microsoft.Maui/VisualDiagnostics.xml" path="//Member[@MemberName='GetXamlSourceInfo']/Docs/*" /> [EditorBrowsable(EditorBrowsableState.Never)] public static SourceInfo? GetSourceInfo(object obj) => sourceInfos.TryGetValue(obj, out var sourceinfo) ? sourceinfo : null; public static void OnChildAdded(IVisualTreeElement parent, IVisualTreeElement child) { if (!VisualDiagnostics.IsEnabled) return; if (child is null) return; var index = parent?.GetVisualChildren().IndexOf(child) ?? -1; OnChildAdded(parent, child, index); } public static void OnChildAdded(IVisualTreeElement? parent, IVisualTreeElement child, int newLogicalIndex) { if (!VisualDiagnostics.IsEnabled) return; if (child is null) return; OnVisualTreeChanged(new VisualTreeChangeEventArgs(parent, child, newLogicalIndex, VisualTreeChangeType.Add)); } public static void OnChildRemoved(IVisualTreeElement parent, IVisualTreeElement child, int oldLogicalIndex) { if (!VisualDiagnostics.IsEnabled) return; OnVisualTreeChanged(new VisualTreeChangeEventArgs(parent, child, oldLogicalIndex, VisualTreeChangeType.Remove)); } public static event EventHandler<VisualTreeChangeEventArgs>? VisualTreeChanged; static void OnVisualTreeChanged(VisualTreeChangeEventArgs e) { VisualTreeChanged?.Invoke(e.Parent, e); } public static async Task<byte[]?> CaptureAsPngAsync(IView view) { var result = await view.CaptureAsync(); return await ScreenshotResultToArray(result, ScreenshotFormat.Png, 100); } public static async Task<byte[]?> CaptureAsJpegAsync(IView view, int quality = 80) { var result = await view.CaptureAsync(); return await ScreenshotResultToArray(result, ScreenshotFormat.Jpeg, quality); } public static async Task<byte[]?> CaptureAsPngAsync(IWindow window) { var result = await window.CaptureAsync(); return await ScreenshotResultToArray(result, ScreenshotFormat.Png, 100); } public static async Task<byte[]?> CaptureAsJpegAsync(IWindow window, int quality = 80) { var result = await window.CaptureAsync(); return await ScreenshotResultToArray(result, ScreenshotFormat.Jpeg, quality); } static async Task<byte[]?> ScreenshotResultToArray(IScreenshotResult? result, ScreenshotFormat format, int quality) { if (result is null) return null; using var ms = new MemoryStream(); await result.CopyToAsync(ms, format, quality); return ms.ToArray(); } } }