如何在WPF中创建一个半透明表单
问题描述:
我必须在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>
答
首先,你需要设置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
只能如果WindowStyle
组被设置为True
到None
。
更新: 如果你不想设置WindowStyle
到None
,并希望保持非标准边框和窗口按钮也将在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);
}
表单在WPF中不存在;你是指一个窗口......还是不同的东西? – 2011-02-07 14:18:52
关于“Pavlo Glazkov,你对这个解决方案有什么看法”......好吧,很难说。这取决于你的目标。如果这种边界是你想要的,那么这是一条路。唯一的问题是,在这种情况下,你有绝对透明的窗口。你实际上可以点击它。如果这不是所需的行为,则应将背景设置为不完全透明的颜色。 – 2011-02-07 20:07:11
@ Pavlo Glazkov - 你说的对,这种类型的答案只是临时解决方案。基本上我很惊讶地发现MS没有在WPF中提供这种功能。我知道在2005年有些冗长而复杂的代码使用API来实现这种功能,但现在是2011年,我们仍然需要编写冗长的代码,它很丑陋。那么你谈论的那些颜色不是完全透明的颜色? – Student 2011-02-07 20:56:09