C# 更改窗口不透明度,使子项保持不变

C# 更改窗口不透明度,使子项保持不变,c#,wpf,C#,Wpf,我对WPF中窗口的不透明度有一个问题,我想做的是更改窗口的不透明度,但保持子窗口的不透明度不变 这是我目前的代码: Window window = new Window(); window.WindowStyle = WindowStyle.None; window.AllowsTransparency = true; window.Background = Brushes.Black; window.Opacity = 0.5; window.ShowInTas

我对WPF中窗口的不透明度有一个问题,我想做的是更改窗口的不透明度,但保持子窗口的不透明度不变

这是我目前的代码:

      Window window = new Window();
  window.WindowStyle = WindowStyle.None;
  window.AllowsTransparency = true;
  window.Background = Brushes.Black;
  window.Opacity = 0.5;
  window.ShowInTaskbar = false;

  double taskBarHeight = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height - System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
  window.Height = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height - taskBarHeight;
  window.Width = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
  window.Top = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Top;
  window.Left = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Left;

  LoginCtl ctl = new LoginCtl(this);

  window.Content = ctl;
  window.ShowDialog();

我知道孩子们的不透明度不能比他们的父母高,但是有没有解决办法呢?

好吧,你可以让你的窗口保持正常的不透明度,但是改变背景的透明度(alpha通道)。如果这还不够,并且您还想更改chrome元素的不透明度,您可以尝试自己修改它。请参阅。

好的,您可以让您的窗口保持正常的不透明度,但可以更改背景的透明度(alpha通道)。如果这还不够,并且您还想更改chrome元素的不透明度,您可以尝试自己修改它。请参阅。

了解窗口不透明度的工作原理可能会有所帮助。它是在硬件中实现的,这是视频适配器的一个功能,称为“覆盖”。它通过WS_EX_分层窗口样式标志和。转到该函数的MSDN库页面,查看可能的功能

视频适配器有一个混频器,可以组合两个视频内存缓冲区的像素。该混合器支持两种效果,alpha混合和颜色键控。分别是api函数中的bAlpha和crKey参数。Alpha混合是您在这里所追求的,它使用乘法器组合两个缓冲区的像素。alpha乘数越低,像素对发送到监视器的最终像素值的贡献越小。颜色键控是视频处理中的常见技巧,天气预报员在天气图前,当一个像素与颜色键匹配时,它将被另一个缓冲区中的像素替换。颜色键控不直接在WPF中公开,但它在Winforms中具有Form.TransparencyKey属性。WPF使用每像素alpha,它使用32bpp像素绘制,包括alpha组件,这与Winforms使用的旧本机Windows组件不同,Winforms使用24bpp GDI调用绘制

也许您可以告诉我们为什么现在会出现这个问题,winapi将效果限制在一个窗口中。另外还要求它必须是顶级窗口,这与WPF窗口类是一样的。因此,alpha混合效果将应用于窗口中的所有像素,对于用于渲染控件的窗口部分,不能有选择地将其禁用

请注意链接文章中的注释,Windows 8也支持为子窗口指定它。这几乎肯定是由DWM完成的,DWM是桌面窗口管理器,在启用Aero时启用。在软件而不是硬件中完成,windows被渲染到内存中,DWM在将像素发送到视频适配器之前合成它们。该功能尚未在.NET中公开,需要时间。无论如何,对WPF不是很有用,因为WPF不像Winforms那样使用子窗口


足够的介绍,以了解您需要做什么来解决此问题。你需要自己做分层。你需要两扇窗户,一扇叠在另一扇上。底部的窗口应该是一个只有不透明度设置的普通窗口。它提供了背景。然后,需要另一个包含控件的窗口,窗口样式设置为“无”,背景设置为“透明”,以便可以看到底部窗口渲染的背景像素。它的所有者应设置为底部窗口,以便它始终位于顶部,当用户移动底部窗口或调整其大小时,您需要移动并调整其大小。

了解窗口不透明度的工作原理可能会有所帮助。它是在硬件中实现的,这是视频适配器的一个功能,称为“覆盖”。它通过WS_EX_分层窗口样式标志和。转到该函数的MSDN库页面,查看可能的功能

视频适配器有一个混频器,可以组合两个视频内存缓冲区的像素。该混合器支持两种效果,alpha混合和颜色键控。分别是api函数中的bAlpha和crKey参数。Alpha混合是您在这里所追求的,它使用乘法器组合两个缓冲区的像素。alpha乘数越低,像素对发送到监视器的最终像素值的贡献越小。颜色键控是视频处理中的常见技巧,天气预报员在天气图前,当一个像素与颜色键匹配时,它将被另一个缓冲区中的像素替换。颜色键控不直接在WPF中公开,但它在Winforms中具有Form.TransparencyKey属性。WPF使用每像素alpha,它使用32bpp像素绘制,包括alpha组件,这与Winforms使用的旧本机Windows组件不同,Winforms使用24bpp GDI调用绘制

也许您可以告诉我们为什么现在会出现这个问题,winapi将效果限制在一个窗口中。另外还要求它必须是顶级窗口,这与WPF窗口类是一样的。因此,alpha混合效果将应用于窗口中的所有像素,对于用于渲染控件的窗口部分,不能有选择地将其禁用

请注意链接文章中的注释,Windows 8也支持为子窗口指定它。这几乎肯定是由DWM完成的,DWM是桌面窗口管理器,在启用Aero时启用。在软件而不是硬件中完成,windows被渲染到内存中,DWM在将像素发送到视频适配器之前合成它们。该功能尚未在.NET中公开,需要时间。无论如何,对WPF不是很有用,因为WPF不像Winforms那样使用子窗口

足够的介绍,以了解您需要做什么来解决此问题。你需要自己做分层。你需要两扇窗户,一扇叠在另一扇上。底部的窗口应该是一个只有不透明度设置的普通窗口。It公关
    <Grid Name="MainGrid">
    <Rectangle Fill="Gray" Opacity="0.7" />
    </Grid>
  LoginWindow win = new LoginWindow();
  win.ShowInTaskbar = false;

  LoginCtl ctl = new LoginCtl(this);
  win.MainGrid.Children.Add(ctl);
  win.ShowDialog();