gpt4 book ai didi

wpf - 最大自定义窗口丢失阴影效果

转载 作者:行者123 更新时间:2023-12-03 21:04:19 26 4
gpt4 key购买 nike

我有一个自定义的 WPF 窗口,定义为:

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" MinHeight="300" Height="350" MinWidth="600" Width="700" ResizeMode="CanResizeWithGrip" AllowsTransparency="True" WindowStyle="None">

我在网上找到了一个创建阴影的类(class),如下所示。即使使用调整大小的 handle ,这也很有效,直到我最大化窗口。一旦我最大化窗口或更改另一个窗口(例如 Visual Studio)的窗口状态,我就会失去阴影并且无法恢复它。有任何想法吗?

投影类:

Public Class DropShadow

Private Shared _handler As EventHandler = New EventHandler(AddressOf window_SourceInitialized)

<DllImport("dwmapi.dll", PreserveSig:=True)> _
Private Shared Function DwmSetWindowAttribute(hwnd As IntPtr, attr As Integer, ByRef attrValue As Integer, attrSize As Integer) As Integer

End Function

<DllImport("dwmapi.dll")> _
Private Shared Function DwmExtendFrameIntoClientArea(hWnd As IntPtr, ByRef pMarInset As Margins) As Integer
End Function

Public Shared Sub DropShadowToWindow(window As Window)
If Not DropShadow(window) Then
AddHandler window.SourceInitialized, _handler
AddHandler window.SizeChanged, New SizeChangedEventHandler(AddressOf windowSizeChanged)
End If
End Sub

Private Shared Sub window_SourceInitialized(sender As Object, e As EventArgs)
Dim window As Window = DirectCast(sender, Window)

DropShadow(window)

RemoveHandler window.SourceInitialized, _handler
End Sub


Private Shared Function DropShadow(window As Window) As Boolean
Try
Dim helper As New WindowInteropHelper(window)
Dim val As Integer = 2
Dim ret1 As Integer = DwmSetWindowAttribute(helper.Handle, 2, val, 4)

If ret1 = 0 Then
Dim m As New Margins() With { _
.Bottom = 0, _
.Left = 0, _
.Right = 0, _
.Top = 0 _
}
Dim ret2 As Integer = DwmExtendFrameIntoClientArea(helper.Handle, m)
Return ret2 = 0
Else
Return False
End If
Catch ex As Exception
' Probably dwmapi.dll not found (incompatible OS)
Return False
End Try
End Function

Private Shared Sub windowSizeChanged(sender As Object, e As SizeChangedEventArgs)
Dim window As Window = DirectCast(sender, Window)
DropShadow(window)
End Sub
End Class

最佳答案

所以我找到了一种方法来让它发挥作用。

您需要使用 WPF Shell 集成库 ( here ) 为您完成这项工作。由于它是由 MS 编写的,因此他们已修复(似乎)对 P/Invoke 代码执行操作的任何问题。

因此,很容易获得一个没有 Aero 玻璃、可在边缘调整大小、具有与 Aero snap 相同的标题区域以及在最小/最大化后重新出现的投影的窗口。

这是我的窗口的代码(注意,您需要引用 Microsoft.Windows.Shell )

<Window x:Class="MyLibrary.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="http://schemas.microsoft.com/winfx/2006/xaml/presentation/shell"
Title="MainWindow"
WindowStyle="SingleBorderWindow"
ResizeMode="CanResizeWithGrip"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="449"
d:DesignWidth="677"
Foreground="White"
Background="Black">

<shell:WindowChrome.WindowChrome>
<shell:WindowChrome CaptionHeight="35"
GlassFrameThickness="0,0,0,1"
ResizeBorderThickness="5" />
</shell:WindowChrome.WindowChrome>

<Grid x:Name="LayoutRoot">

</gGrid>
</Window>
<shell:WindowChrome>是您为互操作设置所有不同变量的地方。
  • CaptionHeight :这是标题区域(标题栏)的高度,它允许 Aero 捕捉、双击行为,就像普通标题栏一样。
  • GlassFrameThickness :将其设置为 0,0,0,1出于某种原因,移除了 Chrome (玻璃),保留了方形边框,并添加了阴影。
  • ResizeBorderThickness :这是窗口边缘的厚度,您可以在此处调整窗口大小。

  • 在保持 Window.WindowStyle 属性等于 SingleBorderWindow 时要注意的其他事项并让 Shell 库处理删除标题、按钮和其他镶边。

    所以我有点在那里浪费了我的赏金,但它看起来像是一个完全可行的解决方案,可以很好地享受!

    编辑:

    这是结果的图片: Sample Metro WPF Application

    我还在 http://code.google.com/p/sample-metro-wpf-application/ 上放了一个示例项目.这是一个 MIT 许可证,人们可以随意使用它。

    关于wpf - 最大自定义窗口丢失阴影效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7369115/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com