001 Avalonia UI에서 창 테두리 커스터마이징
버전 Avalonia 11.0.0
- 참고 자료
-
AvaloniaUI(二、无边框窗口) https://www.cnblogs.com/wuyaxiansheng/p/17584413.html
-
서론
데스크톱 애플리케이션을 개발할 때 항상 창 테두리를 어떻게 커스터마이징할지에 대해 관심을 가집니다. 또 다른 소프트웨어를 사용할 때도 이 점을 주시하게 되는데, UWP에 접근하지 않은 이유 중 하나는 UWP가 항상 같은 스타일의 테두리를 사용하기 때문입니다. 이는 과거 Surface와 같은 터치 장치를 위해 만들어진 것이기 때문에 어쩔 수 없는 부분입니다.
어쨌든 이 글에서는 다양한 API를 통해 테두리를 커스터마이징하는 방법과 테두리 효과를 비교하는 방법을 제공하겠습니다.
글의 마지막에 간단한 예제 코드가 있습니다
이 글에서는 두 가지 추천 방법을 소개하며, 글 내부에 추천 표시가 되어 있습니다. 이 두 가지 방법은 저에게 매우 마음에 듭니다.
- Avalonia의 Window 객체
WPF의 일부 경험은 Avalonia에서 적용되지 않을 수 있습니다. 창 테두리를 커스터마이징하는 주요 작업 객체는 Avalonia의 Window 객체입니다. 제 프로젝트는 DesktopApp이라고 하며, DesktopApp/Views/MainWindow.axaml에서 해당 axaml 파일을 찾을 수 있습니다. 이 파일은 DesktopApp.Desktop 프로젝트에 있지 않다는 점에 주의하세요.
튜토리얼의 스크린샷을 위해 의도적으로 크기와 배경색을 변경했으며, 다음은 해당 코드입니다. 이 부분은 다른 분들에게는 영향이 없습니다.
<Window x:Class="DesktopApp.Views.MainWindow"
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"
xmlns:views="clr-namespace:DesktopApp.Views"
xmlns:vm="using:DesktopApp.ViewModels"
Title="데스크톱 앱"
Width="350"
Height="250"
Background="LightBlue"
Icon="/Assets/app-icon.ico"
mc:Ignorable="d">
<views:MainView />
</Window>
- API 소개
참고: Avalonia는 사용자 정의 창 테두리를 ClientArea의 Extended 확장으로 부릅니다. 이해하기 쉽게 본 글에서는 이 개념을 일반적으로 테두리라고 부르겠습니다. 물론 원문은 그대로 유지하겠습니다.
1. Window.ExtendClientAreaToDecorationsHint 속성 (강력 추천 방법 중 하나)
class Window
{
// 사용자 콘텐츠 영역이 제목 표시줄로 확장되는지 여부를 읽거나 설정합니다.
// Gets or sets if the ClientArea is Extended into the Window Decorations (chrome or border).
public bool ExtendClientAreaToDecorationsHint {get;set;}
}
이 속성이 Is로 시작하지 않는다는 점이 놀라웠습니다. 이 속성은 사용자 콘텐츠가 제목 표시줄로 확장될 수 있는지를 제어합니다. 다른 관점에서 보면, 제목 표시줄의 콘텐츠가 사용자 콘텐츠 영역으로 이동되는 것과 같습니다.
기본적으로 ExtendClientAreaToDecorationsHint = false입니다.
ExtendClientAreaToDecorationsHint = true로 설정하면 다음과 같습니다.
이전 이미지와 비교하면 제목 표시줄과 콘텐츠가 하나로 통합된 것을 볼 수 있지만, 제목과 아이콘이 사라진 점에 주의하세요.
2. Window.ExtendClientAreaChromeHints 속성
// 테두리 스타일 유형에 대한 설명
// Hint for Window Chrome when ClientArea is Extended.
[Flags]
public enum ExtendClientAreaChromeHints
{
// 테두리 없음
// The will be no chrome at all.
NoChrome = 0,
// 시스템 테두리 사용
// Use SystemChrome
SystemChrome = 1,
// 플랫폼 기본값
// The default for the platform.
Default = 2,
// 가능한 경우 시스템 테두리 우선 사용, OSX에서는 OSX 테두리 스타일, Windows에서는 Windows 테두리 스타일 사용
// Use system chrome where possible. OSX system chrome is used, Windows managed
// chrome is used. This is because Windows Chrome can not be shown on top of user
// content.
PreferSystemChrome = 2,
// OSX에서 제목 표시줄이 더 두꺼운 도구 모음 제목 표시줄이 됩니다.
// 제목 표시줄 세 버튼의 위치가 일반 스타일보다 약간 낮게 표시됩니다.
// On OSX the titlebar is the thicker toolbar kind.
// Causes traffic lights to be positioned slightly lower than normal.
OSXThickTitleBar = 8
}
class Window
{
// Avalonia.Platform.ExtendClientAreaChromeHints를 설정하여 클라이언트 영역이 확장될 때 테두리의 모양을 제어합니다.
// Gets or Sets the Avalonia.Platform.ExtendClientAreaChromeHints that control how the chrome looks when the client area is extended.
public ExtendClientAreaChromeHints ExtendClientAreaChromeHints {get;set;}
}
Avalonia의 Window에는 ExtendClientAreaChromeHints 속성이 있으며, 값의 형식은 열거형 ExtendClientAreaChromeHints입니다. 이 열거형 형식은 [Flag] 특성을 가지고 있어 일부 특성을 함께 사용할 수 있습니다.
참고: ExtendClientAreaChromeHints만 사용하는 것은 효과가 없습니다. 다른 속성과 함께 사용해야 하며, ExtendClientAreaToDecorationsHint = true를 설정해야 합니다.
2.1 테두리 없음 (강력 추천 방법 중 다른 하나)
ExtendClientAreaChromeHints="NoChrome"
ExtendClientAreaToDecorationsHint="True"
창에 테두리가 있는지 여부를 논의할 때 창을 드래그할 수 있는지 여부도 고려해야 할 요소입니다. NoChrome으로 설정하면 이 창은드래그가 가능합니다.
2.2 기본값
ExtendClientAreaChromeHints="Default"
ExtendClientAreaToDecorationsHint="True"
이것은 ExtendClientAreaToDecorationsHint = true만 활성화했을 때의 모양입니다. 보기에도 좋습니다.
3. Window.ExtendClientAreaTitleBarHeightHint
제목 표시줄 높이를 설명하는 속성으로, 제목 표시줄 높이는 드래그 가능한 영역의 크기를 결정합니다.
class Window
{
// 클라이언트 영역이 확장될 때 제목 표시줄 높이를 설정합니다.
// -1은 시스템 기본값을 의미합니다.
// 다른 양수 값은 제목 표시줄의 높이에 영향을 줍니다.
// Gets or Sets the TitlebarHeightHint for when the client area is extended.
// A value of -1 will cause the titlebar to be auto sized to the OS default.
// Any other positive value will cause the titlebar to assume that height.
public double Window.ExtendClientAreaTitleBarHeightHint { get; set; }
}
드래그를 원하지 않는다면 0으로 설정하세요.
4. Window.SystemDecorations
// 시스템 테두리 모양
// Determines system decorations (title bar, border, etc) for a Avalonia.Controls.Window
public enum SystemDecorations
{
// 테두리 없음
// No decorations
None = 0,
// 제목 표시줄 없음
// Window border without titlebar
BorderOnly = 1,
// 모두 포함
// Fully decorated (default)
Full = 2
}
4.1 제목 표시줄 없음
이 창은 매우 크며 Window의 Width와 Height 설정도 무효화됩니다. 원래는 작은 크기로 설정했습니다.
SystemDecorations="BorderOnly"
4.2 빈 스타일
이 기능은 매우 이상적입니다. 하지만 드래그가무효하지만, 이것도 매우 합리적입니다. 이것이 표준 스타일입니다.
SystemDecorations="None"
- 배경 투명화 방법
배경을 직접 Transparent로 설정하는 것은 매우 좋은 선택입니다.
Background="Transparent"
SystemDecorations="None"
- 간단한 예제 코드
<Window x:Class="DesktopApp.Views.MainWindow"
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"
xmlns:views="clr-namespace:DesktopApp.Views"
xmlns:vm="using:DesktopApp.ViewModels"
Title="데스크톱 앱"
Width="400"
Height="300"
Background="Transparent"
SystemDecorations="None"
Icon="/Assets/app-icon.ico"
mc:Ignorable="d">
<Grid>
<Border Margin="30"
Background="White"
BoxShadow="0 8 25 5 #44000000"
CornerRadius="12" />
<views:MainView />
</Grid>
</Window>