今天开始继续Avalonia练习。
本节:CefNet
1.引入
CefNet.Avalonia.Eleven
2.项目引入
Program中加入
using Avalonia;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using CefNet;
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;namespace CefAvalonia
{internal sealed class Program{internal static CefAppImpl? app;private static DispatcherTimer? messagePump;private const int messagePumpDelay = 10;// Initialization code. Don't use any Avalonia, third-party APIs or any// SynchronizationContext-reliant code before AppMain is called: things aren't initialized// yet and stuff might break.[STAThread]public static void Main(string[] args){string cefPath = GetProjectPath(PlatformInfo.IsMacOS);bool externalMessagePump = args.Contains("--external-message-pump");if (PlatformInfo.IsMacOS){externalMessagePump = true;}var settings = new CefSettings();settings.MultiThreadedMessageLoop = !externalMessagePump;settings.ExternalMessagePump = externalMessagePump;settings.NoSandbox = true;settings.WindowlessRenderingEnabled = true;settings.LocalesDirPath = Path.Combine(cefPath, PlatformInfo.IsMacOS ? "Resources" : "locales");settings.ResourcesDirPath = Path.Combine(cefPath, PlatformInfo.IsMacOS ? "Resources" : "");settings.LogSeverity = CefLogSeverity.Warning;settings.UncaughtExceptionStackSize = 8;App.FrameworkInitialized += App_FrameworkInitialized;App.FrameworkShutdown += App_FrameworkShutdown;app = new CefAppImpl();app.ScheduleMessagePumpWorkCallback = OnScheduleMessagePumpWork;app.Initialize(cefPath, settings);BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);}private static string GetProjectPath(bool isMacOS){return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".cefnet", "Release", isMacOS ? Path.Combine("cefclient.app", "Contents", "Frameworks", "Chromium Embedded Framework.framework") : "");}private static void App_FrameworkInitialized(object? sender, EventArgs e){if (CefNetApplication.Instance.UsesExternalMessageLoop){messagePump = new DispatcherTimer(TimeSpan.FromMilliseconds(messagePumpDelay), DispatcherPriority.Normal, (s, e) =>{CefApi.DoMessageLoopWork();Dispatcher.UIThread.RunJobs();});messagePump.Start();}}private static void App_FrameworkShutdown(object? sender, EventArgs e){messagePump?.Stop();}private static async void OnScheduleMessagePumpWork(long delayMs){await Task.Delay((int)delayMs);Dispatcher.UIThread.Post(CefApi.DoMessageLoopWork);}// Avalonia configuration, don't remove; also used by visual designer.public static AppBuilder BuildAvaloniaApp()=> AppBuilder.Configure<App>().UsePlatformDetect().WithInterFont().LogToTrace().UseReactiveUI();}
}
APP中加入
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using CefAvalonia.ViewModels;
using CefAvalonia.Views;
using System;namespace CefAvalonia
{public partial class App : Application{public static event EventHandler? FrameworkInitialized;public static event EventHandler? FrameworkShutdown;public override void Initialize(){AvaloniaXamlLoader.Load(this);}public override void OnFrameworkInitializationCompleted(){if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop){desktop.MainWindow = new MainWindow{DataContext = new MainWindowViewModel(),};}base.OnFrameworkInitializationCompleted();}}
}
添加一个实现处理类
using CefNet;
using System;
using System.Runtime.InteropServices;namespace CefAvalonia
{internal class CefAppImpl:CefNetApplication{protected override void OnBeforeCommandLineProcessing(string processType, CefCommandLine commandLine){base.OnBeforeCommandLineProcessing(processType, commandLine);if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)){commandLine.AppendSwitch("no-zygote");commandLine.AppendSwitch("no-sandbox");}}public Action<long> ScheduleMessagePumpWorkCallback { get; set; }protected override void OnScheduleMessagePumpWork(long delayMs){ScheduleMessagePumpWorkCallback(delayMs);}}
}
窗口后台
using Avalonia.Controls;
using CefNet.Avalonia;namespace CefAvalonia.Views
{public partial class MainWindow : Window{public MainWindow(){InitializeComponent();WebView webview = new() { Focusable = true };Content = webview;webview.BrowserCreated += (s, e) => webview.Navigate("https://www.baidu.com");webview.DocumentTitleChanged += (s, e) => Title = e.Title;Closing += (s, e) => Program.app?.Shutdown();}}
}
最后,下载对应的库
CEF Automated Builds (spotifycdn.com)
运行效果