Closed Naylor55 closed 9 months ago
Try lates nightly builds, where we have DirectComposition available on Windows backend.
If the windows Server 2016 theme is set to dark, the background is black; If the windows Server 2016 theme is set to light color, the background is white. It's so interesting,Although my code has made the background transparent
RequestedThemeVariant follows system by default. So expected here if transparent fails. Does transparent works on other platforms for you btw? (edit: saw it just now)
@maxkatz6 Is your suggestion for me to switch the nuget package source to avalonia-nighty ? I found a wiki and followed it, but the background still cannot be transparent on Windows Server 2016 OS
After multiple attempts, I found that on Windows Server 2016, controls (eg:Border)can have background transparency, while window cannot have background transparency.
@Naylor55 what is your TransparencyLevelHint="Transparent"
set to on MainWindow?
@timunie I have tried many ways:
<Window
......
Background="Transparent"
>
<Window
......
>
<Window.Styles>
<Style Selector="Window">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="White" Opacity="0"></SolidColorBrush>
</Setter.Value>
</Setter>
</Style>
</Window.Styles>
or
<Window.Background>
<SolidColorBrush Color="Transparent" />
</Window.Background>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
//根据窗体的类名或者标题名来找到窗口的句柄
[DllImport("user32.dll", EntryPoint = "FindWindow")]
private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
//指定扩展窗口,以便控制窗口的透明度
[DllImport("user32", EntryPoint = "SetWindowLong")]
private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);
//设置窗体的透明度,dwFlags指定为2时,bAlpha才能起作用
[DllImport("user32", EntryPoint = "SetLayeredWindowAttributes")]
private static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, int bAlpha, int dwFlags);
[DllImport("user32", EntryPoint = "UpdateWindow")]
private static extern uint UpdateWindow(IntPtr hwnd);
private const uint WS_EX_LAYERED = 0x80000;
private const int GWL_EXSTYLE = (-20); //设置为分层窗口 20 才能进行控制
private const int LWA_ALPHA = 0x2;
/// <summary>
///
/// </summary>
/// <param name="handle"></param>
/// <param name="windowName"></param>
/// <param name="windowOpacity">范围从 0(完全透明)到 255(完全不透明)</param>
public static void changeOpacity(IPlatformHandle handle, string windowName, int windowOpacity)
{
uint v = SetWindowLong(handle.Handle, GWL_EXSTYLE, WS_EX_LAYERED);
int v1 = SetLayeredWindowAttributes(handle.Handle, 0, windowOpacity, LWA_ALPHA);
UpdateWindow(handle.Handle);
}
private void Button_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
IPlatformHandle? platformHandle = this.TryGetPlatformHandle();
changeOpacity(platformHandle, "", 0);
Button b = new Button();
b.Width = 100;
b.Height = 100;
b.Background = Brushes.Red;
this.Content = b;
}
}
These methods have all failed in Windows Server 2016 .
and then , I found a wiki ,the wiki tell me can call TopLevel.ActualTransparencyLevel to know platform was able to provide TransparencyLevel is .
TopLevel topLevel = TopLevel.GetTopLevel(this);
WindowTransparencyLevel actualTransparencyLevel = topLevel.ActualTransparencyLevel;
string v = actualTransparencyLevel.ToString();
so , my current conclusion is that windows server 2016 does not support Window Transparency
I still don't see where you set TransparencyLevelHint
? This is a property that can be set by you. The defaults may differ per OS.
@timunie Is it like this?
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
TopLevel topLevel = TopLevel.GetTopLevel(this);
WindowTransparencyLevel actualTransparencyLevel = topLevel.ActualTransparencyLevel;
string v = actualTransparencyLevel.ToString();
LogUtil.SetLogTx(v);
List<WindowTransparencyLevel> list = new List<WindowTransparencyLevel>();
list.Add(WindowTransparencyLevel.Transparent);
topLevel.TransparencyLevelHint = list;
WindowTransparencyLevel actualTransparencyLevel2 = topLevel.ActualTransparencyLevel;
string v2 = actualTransparencyLevel.ToString();
LogUtil.SetLogTx(v2);
}
}
I tried setting it up through topLevel.TransparencyLevelHint =Transparent , and after setting it up, I obtained topLevel.ActualTransparencyLevel, it is still None .
no idea if that is supported that way. I only have used that property in XAML directly
@timunie aha
I'm having the feeling that Windows Server does not support it correctly. So seems to be by design. See also: https://learn.microsoft.com/en-us/answers/questions/766907/window-cannot-be-made-transparent-half-transparent
@timunie ok,thanks!!!
Describe the bug
Setting background transparency does not work on Windows Server 2016 systems
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Expected behavior can achieve transparency in both Windows11 and WindowsServer2016, but in reality, it is only transparent in Windows11
Screenshots
Windows11:
Windows Server 2016:
Environment
Additional context
I have attempted to modify the rendering engine to Avalonia Direct2D1 , Not solving this problem 。