如何在WPF中创建半透明表单

时间:2011-02-07 14:07:07

标签: wpf

我必须在WPF中开发一个半透明的表单,但控件不应该是透明的。

我尝试过不同的设置,例如设置opacity = 0.5但没有结果。

  • 我知道只有当WindowStyle设置为None时,AllowTransparency才能设置为True,但我还需要显示Border

更新 Pavlo Glazkov,您对此解决方案有何看法

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" Opacity="1" AllowsTransparency="True" WindowStyle="None" Background="Transparent">
<Grid Background="Transparent">
    <Border Margin="2,2,12,34" Name="border1" BorderBrush="Lavender" BorderThickness="5" CornerRadius="20,0,20,0"></Border>
    <Button Height="23" Margin="93,101,110,0" Name="button1" VerticalAlignment="Top" Background="CadetBlue" Foreground="White">Hello WPF</Button>
    <Button Height="24" Margin="0,8,20,0" Name="button2" VerticalAlignment="Top" HorizontalAlignment="Right" Width="21" Click="button2_Click">X</Button>
</Grid>
</Window>

2 个答案:

答案 0 :(得分:13)

首先,您需要将AllowTransperency设置为True。然后,您可以将窗口的背景设置为透明(达到所需范围)画笔:

<Window x:Class="MyWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStyle="None"
        AllowsTransparency="True"
        Background="{DynamicResource WindowBackground}">
    <Window.Resources>
       <SolidColorBrush x:Key="WindowBackground" 
                        Color="White"
                        Opacity="0.5"/>
    </Window.Resources>
    ...
</Window>

请注意,AllowTransperency只有在True设置为WindowStyle时才能设置为None

<强>更新 如果您不想将WindowStyle设置为None并希望保留标准边框和窗口按钮,则可以选择仅适用于具有Windows Aero主题的Windows Vista / 7。

诀窍是你可以使用以下代码将“Glass”区域扩展到整个窗口:

public static class WindowUtils
{
    /// <summary>
    /// Extends the glass area into the client area of the window
    /// </summary>
    /// <param name="window">Window to extend the glass on.</param>
    /// <param name="thikness">Thickness of border to extend.</param>
    public static void ExtendGlass(this Window window, Thickness thikness) {
        try {
            int isGlassEnabled = 0;
            Win32.DwmIsCompositionEnabled(ref isGlassEnabled);
            if (Environment.OSVersion.Version.Major > 5 && isGlassEnabled > 0) {
                // Get the window handle
                var helper = new WindowInteropHelper(window);
                var mainWindowSrc = HwndSource.FromHwnd(helper.Handle);

                if (mainWindowSrc != null) {
                    if (mainWindowSrc.CompositionTarget != null) {
                        mainWindowSrc.CompositionTarget.BackgroundColor = Colors.Transparent;
                    }

                    // Get the dpi of the screen
                    System.Drawing.Graphics desktop =
                        System.Drawing.Graphics.FromHwnd(mainWindowSrc.Handle);

                    float dpiX = desktop.DpiX / 96;
                    float dpiY = desktop.DpiY / 96;

                    // Set Margins
                    var margins = new MARGINS {
                        cxLeftWidth = (int)(thikness.Left * dpiX),
                        cxRightWidth = (int)(thikness.Right * dpiX),
                        cyBottomHeight = (int)(thikness.Bottom * dpiY),
                        cyTopHeight = (int)(thikness.Top * dpiY)
                    };

                    window.Background = Brushes.Transparent;

                    Win32.DwmExtendFrameIntoClientArea(mainWindowSrc.Handle, ref margins);
                }
            }
            else {
                window.Background = SystemColors.WindowBrush;
            }
        }
        catch (DllNotFoundException) {

        }
    }
}

public class Win32
{
    [DllImport("dwmapi.dll")]
    public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);

    [DllImport("dwmapi.dll")]
    public static extern int DwmIsCompositionEnabled(ref int en);

    [DllImport("user32.dll")]
    public static extern bool SetCursorPos(int X, int Y);


    [DllImport("User32", EntryPoint = "ClientToScreen", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
    public static extern int ClientToScreen(IntPtr hWnd, [In, Out] POINT pt);
}

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

[StructLayout(LayoutKind.Sequential)]
public class POINT
{
    public int x = 0;
    public int y = 0;
}

要将玻璃扩展到整个窗口,您需要在窗口的SizeChanged事件处理程序中调用ExtendGlass扩展方法,并传递覆盖整个窗口的Thickness

public MyWindow() {
    InitializeComponent();

    SizeChanged += OnSizeChanged;
}

private void OnSizeChanged(object sender, SizeChangedEventArgs e) {
    double horisontalThickness = Width / 2;
    double verticalThickness = Height / 2;

    var glassThickness = new Thickness(horisontalThickness, verticalThickness, horisontalThickness, verticalThickness);

    this.ExtendGlass(glassThickness);
}

答案 1 :(得分:3)

您可以尝试this,它会为您的窗口创建一个Glass Background(看起来像Vista和Windows7透明效果)

Here是微软的进一步解释。