本文记录在 UNO Platform 的桌面窗口项目里,进入和退出全屏窗口的方法,此方法包括 UNO 的 WPF 和 GTK 和 WinUI 版本的实现
在 2024.06 的 5.2.139 的 UNO 版本里面,可通过如下简单方法进入全屏
Microsoft.UI.Xaml.Window window = ...window.AppWindow.SetPresenter(AppWindowPresenterKind.FullScreen);
通过如上方式即可让某个窗口进入全屏
以下为旧实现方法
实现思路是添加抽象的 IPlatformProvider 接口,在接口里面分别添加进入全屏和退出全屏的方法,如以下代码。接着再分别在 Skia.GTK 和 Skia.WPF 和 WinUI 平台上实现对接方法。所谓跨平台,就是各个平台都实现一遍
public interface IPlatformProvider{ void EnterFullScreen(); void ExitFullScreen();}
为了方便让 UNO 统一平台的项目可以方便使用,再定义一个静态类,用于注入 IPlatformProvider 的各个平台的实现。此处如果依赖注入机制方便对接的话,也可以对接一份进入到容器里,如果不方便对接,那就继续沿用静态类型
public static class PlatformHelper{ public static IPlatformProvider? PlatformProvider { get => _platformProvider; set { if (_platformProvider != null) { throw new InvalidOperationException("PlatformProvider can only be set once"); }
_platformProvider = value; } }
private static IPlatformProvider? _platformProvider;}
以下是各个平台的具体实现
在 WPF 平台下的实现,我使用的是 WPF 稳定的全屏化窗口方法 博客里面提供的方式进行全屏,以下代码省略 FullScreenHelper 的代码,大家可以在本文末尾获取到全部代码
public class PlatformProvider : IPlatformProvider{ public PlatformProvider(Window window) { _window = window; }
private readonly Window _window;
public void EnterFullScreen() { FullScreenHelper.StartFullScreen(_window); }
public void ExitFullScreen() { FullScreenHelper.EndFullScreen(_window); }}
如果想要达成更好的效果,可以使用以下 walterlv 大佬提供的方法,额外设置 WindowChrome 修复边框白边
internal class WindowPlatformProvider : IPlatformProvider { private readonly Window _window; private readonly WindowChrome _windowChrome;
public WindowPlatformProvider(Window window) { _window = window; _windowChrome = new WindowChrome { GlassFrameThickness = WindowChrome.GlassFrameCompleteThickness, CaptionHeight = 32, CornerRadius = new CornerRadius(), ResizeBorderThickness = new Thickness(6), UseAeroCaptionButtons = false, }; WindowChrome.SetWindowChrome(_window, _windowChrome); }
public bool IsFullScreen { get; private set; }
public void EnterFullScreen() { IsFullScreen = true; _window.WindowStyle = WindowStyle.None; WindowChrome.SetWindowChrome(_window, null); FullScreenHelper.StartFullScreen(_window); }
public void ExitFullScreen() { IsFullScreen = false; _window.WindowStyle = WindowStyle.SingleBorderWindow; WindowChrome.SetWindowChrome(_window, _windowChrome); FullScreenHelper.EndFullScreen(_window); } }
对接的代码放在 App.xaml.cs 的 构造 里面,如以下代码
public partial class App : WpfApp{ public App() { var host = new WpfHost(Dispatcher, () => new AppHead()); host.Run(); PlatformHelper.PlatformProvider = new PlatformProvider(MainWindow!); }}
下面是 WinUI 项目里面的定义,代码如下
internal class PlatformProvider : IPlatformProvider{ public PlatformProvider(Window window) { _window = window; }
private readonly Window _window;
public void EnterFullScreen() { _window.AppWindow.SetPresenter(AppWindowPresenterKind.FullScreen); }
public void ExitFullScreen() { _window.AppWindow.SetPresenter(AppWindowPresenterKind.Default); }}
对应的对接代码需要编写在 AppHead.xaml.cs 的 OnLaunched 里面,如以下代码
protected override void OnLaunched(LaunchActivatedEventArgs args) { base.OnLaunched(args);#if WINDOWS10_0_17763_0_OR_GREATER PlatformHelper.PlatformProvider = new PlatformProvider(MainWindow!);#endif MainWindow.SetWindowIcon(); }
额外的关于 UWP 的全屏,请参阅 win10 UWP 全屏
最后是 GTK 项目的平台定义,代码如下
public class GtkPlatformProvider : IPlatformProvider{ public GtkPlatformProvider(GtkHost gtkHost) { _gtkHost = gtkHost; }
private readonly GtkHost _gtkHost;
public void EnterFullScreen() { _gtkHost.Window?.Fullscreen(); }
public void ExitFullScreen() { _gtkHost.Window?.Unfullscreen(); }}
对应的 GTK 对接代码如下
public static void Main(string[] args) { ExceptionManager.UnhandledException += delegate (UnhandledExceptionArgs expArgs) { Console.WriteLine("GLIB UNHANDLED EXCEPTION" + expArgs.ExceptionObject.ToString()); expArgs.ExitApplication = true; };
var host = new GtkHost(() => new AppHead()); PlatformHelper.PlatformProvider = new GtkPlatformProvider(host); host.Run(); }
如果仅需更改 GTK 窗口尺寸,请参阅 UNO.Skia.Gtk 设置窗口尺寸变化方法
以上代码就完成了 UNO 的 WPF 和 GTK 和 WinUI 桌面平台的窗口全屏的实现。为了测试效果,进入 MainPage.xaml 里面添加一个 ToggleButton 按钮,用来控制进入和退出全屏,界面代码如下
<ToggleButton x:Name="FullScreenButton" HorizontalAlignment="Center" VerticalAlignment="Center" Click="FullScreenButton_OnClick">全屏</ToggleButton>
后台代码如下
private void FullScreenButton_OnClick(object sender, RoutedEventArgs e) { var toggleButton = (ToggleButton) sender; if (toggleButton.IsChecked is true) { PlatformHelper.PlatformProvider?.EnterFullScreen(); } else { PlatformHelper.PlatformProvider?.ExitFullScreen(); } }
完成代码之后,分别切换到 UNO 的 WPF 和 GTK 和 WinUI 平台上,进行构建和运行项目。测试点击全屏按钮时,是否能够符合预期的进入和退出全屏模式。如下图是在 UOS 上使用 Skia.GTK 的测试效果
代码放在 github 和 gitee 上,可以使用如下命令行拉取代码
先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git initgit remote add origin https://gitee.com/lindexi/lindexi_gd.gitgit pull origin 0b1371317210b0a5e000484d57ee3ae7fc844e24
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码
git remote remove origingit remote add origin https://github.com/lindexi/lindexi_gd.gitgit pull origin 0b1371317210b0a5e000484d57ee3ae7fc844e24
获取代码之后,进入 RalllawfairlekolairHemyiqearkice 文件夹,即可获取到源代码

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。 欢迎转载、使用、重新发布,但务必保留文章署名 林德熙 (包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我 联系。