gpt4 book ai didi

c# - .net Avalonia 中更改窗口系统顶部栏背景颜色的更简单方法?

转载 作者:行者123 更新时间:2023-12-03 08:30:20 27 4
gpt4 key购买 nike

在 dotnet 的 Avalonia-UI 中框架。我正在使用深色用户界面,并且我设法按照 this example 将所有内容变暗但有一件事:Windows 操作系统中窗口的系统顶部栏。

我在this issue in github中看到过我可以设置属性 HasSystemDecorations="false" 使其消失,但随后我必须自己实现顶部栏的拖动功能、标题、关闭、最大化、最小化等,当我只想更改背景颜色时,这很痛苦。

将窗口顶部栏更改为深色背景颜色的更简单方法是什么?

如果唯一的方法是使用HasSystemDecorations,那么使用关闭/最小化/最大化/拖动的常用功能来实现深色顶栏的最小示例是什么?

最佳答案

是的,您必须设置HasSystemDecorations="false"并实现您自己的标题栏。我在 Github 上有一个基本模板了解如何使用 0.10 版本和 Fluent 主题来执行此操作。

这实际上非常简单,因为 Avalonia 提供了很多方便的方法来实现这一点。

概述:

设置

ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
ExtendClientAreaTitleBarHeightHint="-1"

对于窗口,然后实现一个标题栏。例如,关闭按钮可能如下所示:

<Button Width="46"
VerticalAlignment="Stretch"
BorderThickness="0"
Name="CloseButton"
ToolTip.Tip="Close">
<Button.Resources>
<CornerRadius x:Key="ControlCornerRadius">0</CornerRadius>
</Button.Resources>
<Button.Styles>
<Style Selector="Button:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="Red"/>
</Style>
<Style Selector="Button:not(:pointerover) /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style Selector="Button:pointerover > Path">
<Setter Property="Fill" Value="White"/>
</Style>
<Style Selector="Button:not(:pointerover) > Path">
<Setter Property="Fill" Value="{DynamicResource SystemControlForegroundBaseHighBrush}"/>
</Style>
</Button.Styles>
<Path Margin="10,0,10,0"
Stretch="Uniform"
Data="M1169 1024l879 -879l-145 -145l-879 879l-879 -879l-145 145l879 879l-879 879l145 145l879 -879l879 879l145 -145z"></Path>
</Button>

如果您在控件上设置IsHitTestVisible="False",则可以将下面的窗口拖动到该区域中。因此,将整个标题栏包装在 DockPanel 中:

<DockPanel Background="Black"
IsHitTestVisible="False"
Name="TitleBarBackground"></DockPanel>

现在您显然仍然需要模仿按钮的行为。原则上可以像这样完成(再次查看上面的 Github 存储库的具体示例):

minimizeButton = this.FindControl<Button>("MinimizeButton");
maximizeButton = this.FindControl<Button>("MaximizeButton");
maximizeIcon = this.FindControl<Path>("MaximizeIcon");
maximizeToolTip = this.FindControl<ToolTip>("MaximizeToolTip");
closeButton = this.FindControl<Button>("CloseButton");
windowIcon = this.FindControl<Image>("WindowIcon");

minimizeButton.Click += MinimizeWindow;
maximizeButton.Click += MaximizeWindow;
closeButton.Click += CloseWindow;
windowIcon.DoubleTapped += CloseWindow;

private void CloseWindow(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
Window hostWindow = (Window)this.VisualRoot;
hostWindow.Close();
}

private void MaximizeWindow(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
Window hostWindow = (Window)this.VisualRoot;

if (hostWindow.WindowState == WindowState.Normal)
{
hostWindow.WindowState = WindowState.Maximized;
}
else
{
hostWindow.WindowState = WindowState.Normal;
}
}

private void MinimizeWindow(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
Window hostWindow = (Window)this.VisualRoot;
hostWindow.WindowState = WindowState.Minimized;
}

现在最后一步是您需要根据窗口状态更改最大化按钮的图标。例如,如果您拖动最大化的窗口,它将自动恢复为向下状态,并且最大化按钮的图标需要更改。因此,您需要订阅主机窗口的窗口状态,这可以通过覆盖 Window.HandleWindowStateChanged 来完成。方法或通过执行以下操作:

private async void SubscribeToWindowState()
{
Window hostWindow = (Window)this.VisualRoot;

while (hostWindow == null)
{
hostWindow = (Window)this.VisualRoot;
await Task.Delay(50);
}

hostWindow.GetObservable(Window.WindowStateProperty).Subscribe(s =>
{
hostWindow.Padding = hostWindow.OffScreenMargin;
if (s != WindowState.Maximized)
{
maximizeIcon.Data = Avalonia.Media.Geometry.Parse("M2048 2048v-2048h-2048v2048h2048zM1843 1843h-1638v-1638h1638v1638z");
maximizeToolTip.Content = "Maximize";
}
if (s == WindowState.Maximized)
{
maximizeIcon.Data = Avalonia.Media.Geometry.Parse("M2048 1638h-410v410h-1638v-1638h410v-410h1638v1638zm-614-1024h-1229v1229h1229v-1229zm409-409h-1229v205h1024v1024h205v-1229z");
maximizeToolTip.Content = "Restore Down";
}
});
}

其实上面的代码片段还有一个细节,需要注意一下。至少在窗口上,最大化的窗口实际上比屏幕大。如果您不希望内容超出屏幕范围,则需要为窗口内的主控件添加边距。因此,hostWindowPadding 也会相应更改。Avalonia 提供了一个 IWindowImpl.OffScreenMargin 属性,describes the margin around the window that is offscreen 。您可以直接在窗口的 .axml

中绑定(bind)到此属性
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
ExtendClientAreaTitleBarHeightHint="-1"
Padding="{Binding $self.OffScreenMargin}">

关于c# - .net Avalonia 中更改窗口系统顶部栏背景颜色的更简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65333019/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com