2011-02-07 54 views
7

我必须在WPF中开发一个半透明表单,但控件不应该是transperent。我是WPF的新手。如何在WPF中创建一个半透明表单

我曾尝试不同的东西等预先设置不透明度= 0.5,但没有结果

请在细节和步骤解释一步

谢谢!

  • 我知道AllowTransperency可以被设置为True仅当WindowStyle设置为无,但我需要出示边境以及

UPDATE: 帕夫洛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> 

+3

表单在WPF中不存在;你是指一个窗口......还是不同的东西? – 2011-02-07 14:18:52

+0

关于“Pavlo Glazkov,你对这个解决方案有什么看法”......好吧,很难说。这取决于你的目标。如果这种边界是你想要的,那么这是一条路。唯一的问题是,在这种情况下,你有绝对透明的窗口。你实际上可以点击它。如果这不是所需的行为,则应将背景设置为不完全透明的颜色。 – 2011-02-07 20:07:11

+0

@ Pavlo Glazkov - 你说的对,这种类型的答案只是临时解决方案。基本上我很惊讶地发现MS没有在WPF中提供这种功能。我知道在2005年有些冗长而复杂的代码使用API​​来实现这种功能,但现在是2011年,我们仍然需要编写冗长的代码,它很丑陋。那么你谈论的那些颜色不是完全透明的颜色? – Student 2011-02-07 20:56:09

回答

12

首先,你需要设置AllowTransperencyTrue。然后,可以将窗口的背景设置为透明的(至所需的程度)刷:

<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只能如果WindowStyle组被设置为TrueNone

更新: 如果你不想设置WindowStyleNone,并希望保持非标准边框和窗口按钮也将在Windows Vista/7的唯一工作与Windows Aero主题的替代品。

的技巧是,你可以用下面的代码扩展了“玻璃”区域到整个窗口:

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; 
} 

到玻璃延伸到你需要调用在该ExtendGlass扩展方法整个窗口窗口的SizeChanged事件处理程序,并通过一个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); 
} 
3

你可以尝试this,它会创建一个玻璃背景为你的窗口(看起来像Vista的和Windows7透明效果)

Here是微软进一步的解释。