C# WPF带边框的透明窗口

11

我想制作一个简单的应用程序,它是透明的,但保留“正常”的边框、关闭按钮、最小化和最大化按钮。

我知道如何使用标准方法使窗口透明。

<Window
    WindowStyle="None"
    AllowsTransparency="True"
    Background="Transparent">
</Window>

但这会去除边框和右上角的按钮。我读了这篇帖子:

Transparent window with a border

它提供了一种解决方案,但实际上,我只想保留如果我不使窗口透明时本来就有的标准边框。这意味着我可以移动窗口,调整大小,关闭等等……这可能吗?

2个回答

6

我为这个目的编写了一个快速的TransparencyConverter类,参考了Microsoft.com上的教程

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

namespace WpfApplication2
{
    class TransparencyConverter
    {
        private readonly Window _window;

        public TransparencyConverter(Window window)
        {
            _window = window;
        }

        public void MakeTransparent()
        {
            var mainWindowPtr = new WindowInteropHelper(_window).Handle;
            var mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
            if (mainWindowSrc != null)
                if (mainWindowSrc.CompositionTarget != null)
                    mainWindowSrc.CompositionTarget.BackgroundColor = System.Windows.Media.Color.FromArgb(0, 0, 0, 0);

            var margins = new Margins
            {
                cxLeftWidth = 0,
                cxRightWidth = Convert.ToInt32(_window.Width) * Convert.ToInt32(_window.Width),
                cyTopHeight = 0,
                cyBottomHeight = Convert.ToInt32(_window.Height) * Convert.ToInt32(_window.Height)
            };

            if (mainWindowSrc != null) DwmExtendFrameIntoClientArea(mainWindowSrc.Handle, ref margins);
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct Margins
        {
            public int cxLeftWidth;
            public int cxRightWidth;
            public int cyTopHeight;
            public int cyBottomHeight;
        }

        [DllImport("DwmApi.dll")]
        public static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref Margins pMarInset);
    }
}

一旦您完成这个步骤,请在XAML中添加Transparent Background属性,并订阅Window_Loaded事件并调用MakeTransparent方法:

<Window etc etc Background="Transparent" Loaded="Window_Loaded">

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    var transparencyConverter = new TransparencyConverter(this);
    transparencyConverter.MakeTransparent();
}

以下是翻译的结果:

以下是截图:

截图


1
几乎可以工作了。在Windows 7中看起来可以正常运行,但在Windows 8中不行。有什么建议吗?谢谢! - Stefan Vasiljevic
@StefanVasiljevic 不要以为你在Windows 8上会有太多好运,上面的代码使用了Aero,可惜在Windows 8上不存在。 - JMK
1
@JMK 真可惜。我一直喜欢 Win 7 中的 Aero。希望微软能重新考虑把它加回来。 - Stefan Vasiljevic
类名本身有一个拼写错误:正确的名称应该是TransparencyConverter,而不是TransparancyConverter! - Davide Cannizzo
@DavideCannizzo 谢谢! - JMK

1
我会首先查看背景颜色的rgb(a)颜色中的(alpha)设置。 (alpha)设置为对象颜色设置了不透明度。
尽管我注意到在我发布这篇文章时,有另一篇文章在我的前面,看起来更简洁,可能更适合你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接