无边框窗口投影不透明元素问题

时间:2012-05-14 06:11:02

标签: wpf

我正在尝试在WPF中创建一个无边框窗口。我正在使用link中提到的类。

只要所有元素全部启用(Opacity = 1),这都可以正常工作。如果我将不透明度设置为0.5,它几乎是不可见的。

如果删除投影的代码,则不透明度可以正常工作。我不确定这是什么原因。

该课程与我正在使用的课程相同,如上面的链接所述。我的其余代码如下。

感谢任何帮助:

  • 吉里贾

XAML:

<Window x:Class="Sample.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Sample">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="70"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <TextBox Margin="2" Text="Something" Grid.Row="0"/>
    <Button Grid.Row="1" Content="Something" IsEnabled="False" Opacity="0.7"/>
</Grid>

代码背后:

/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{

    public Window1()
    {
        InitializeComponent();

    }

    /// <summary>
    /// Raises the <see cref="E:System.Windows.FrameworkElement.Initialized"/> event. 
    /// This method is invoked whenever 
    /// <see cref="P:System.Windows.FrameworkElement.IsInitialized"/> is set to true internally.
    /// </summary>
    /// <param name="e">The <see cref="T:System.Windows.RoutedEventArgs"/> 
    /// that contains the event data.</param>
    protected override void OnInitialized(EventArgs e)
    {
        //AllowsTransparency = false;
        ResizeMode = ResizeMode.NoResize;

        WindowStartupLocation = WindowStartupLocation.CenterScreen;
        WindowStyle = WindowStyle.None;

        DwmDropShadow.DropShadowToWindow(this);

        base.OnInitialized(e);
    }
}

helper Class取自上面的链接:

class DwmDropShadow 

{

[DllImport("dwmapi.dll", PreserveSig = true)] 
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize); 

[DllImport("dwmapi.dll")] 
private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMarInset); 

/// <summary> 
/// Drops a standard shadow to a WPF Window, even if the window isborderless. Only works with DWM (Vista and Seven). 
/// This method is much more efficient than setting AllowsTransparency to true and using the DropShadow effect, 
/// as AllowsTransparency involves a huge permormance issue (hardware acceleration is turned off for all the window). 
/// </summary> 
/// <param name="window">Window to which the shadow will be applied</param> 
public static void DropShadowToWindow(Window window) 
{ 
    if (!DropShadow(window)) 
    { 
        window.SourceInitialized += new EventHandler(window_SourceInitialized); 
    } 
} 

private static void window_SourceInitialized(object sender, EventArgs e) 
{ 
    Window window = (Window)sender; 

    DropShadow(window); 

    window.SourceInitialized -= new EventHandler(window_SourceInitialized); 
} 

/// <summary> 
/// The actual method that makes API calls to drop the shadow to the window 
/// </summary> 
/// <param name="window">Window to which the shadow will be applied</param> 
/// <returns>True if the method succeeded, false if not</returns> 
private static bool DropShadow(Window window) 
{ 
    try 
    { 
        WindowInteropHelper helper = new WindowInteropHelper(window); 
        int val = 2; 
        int ret1 = DwmSetWindowAttribute(helper.Handle, 2, ref val, 4); 

        if (ret1 == 0) 
        { 
            Margins m = new Margins { Bottom = 0, Left = 0, Right = 0, Top = 0 }; 
            int ret2 = DwmExtendFrameIntoClientArea(helper.Handle, ref m); 
            return ret2 == 0; 
        } 
        else 
        { 
            return false; 
        } 
    } 
    catch (Exception ex) 
    { 
        // Probably dwmapi.dll not found (incompatible OS) 
        return false; 
    } 
} 

}

3 个答案:

答案 0 :(得分:0)

我不知道你为什么使用dwmapi.dll来使用阴影效果。为什么不使用WPF扩展工具包或presentationframework.Aero(从visual studio中的.NET程序集引用)中的硬件加速阴影效果?

  <ResourceDictionary Source="/presentationframework.Aero;V3.0.0.0;31bf3856ad364e35;component/themes/aero.normalcolor.xaml"/>

  <DropShadowEffect ShadowDepth="2"></DropShadowEffect>

答案 1 :(得分:0)

你走了:))

 <Window x:Class="Test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    AllowsTransparency="True"
    Title="MainWindow"
    Background="Transparent"
    WindowStyle="None"
    Height="350"
    Width="500">
    <Border Background="#ffFEFEFE" CornerRadius="5" BorderThickness="2" Margin="10" BorderBrush="#ffaaaaaa">
    <Border.Effect>
        <DropShadowEffect Direction="270"
                          ShadowDepth="5"
                          Opacity="0.8"
                          BlurRadius="7" />
    </Border.Effect>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="70" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <TextBox Margin="2"
                 Text="Something"
                 Grid.Row="0" />
        <Button Grid.Row="1"
                Content="Something"
                IsEnabled="False"
                Opacity="0.5" />

    </Grid>

  </Border>
</Window>

答案 2 :(得分:0)

对其中一个边距使用非零值,例如。 1,0,0,0;或1,1,1,1;并使用你自己的边距:

    [StructLayout(LayoutKind.Sequential)]
    public struct Margins
    {
        public int Left;
        public int Right;
        public int Top;
        public int Bottom;
    }