5cba597600
- Migliorie varie.
150 lines
4.7 KiB
VB.net
150 lines
4.7 KiB
VB.net
Imports System.Windows.Controls.Primitives
|
||
Imports System.Windows.Interop
|
||
|
||
Public Class EgtPopup
|
||
Inherits Popup
|
||
|
||
''' <summary>
|
||
''' Is Topmost dependency property
|
||
''' </summary>
|
||
Public Shared ReadOnly IsTopmostProperty As DependencyProperty = DependencyProperty.Register("IsTopmost", GetType(Boolean), GetType(EgtPopup), New FrameworkPropertyMetadata(False, New PropertyChangedCallback(AddressOf OnIsTopmostChanged)))
|
||
|
||
Private _appliedTopMost As System.Nullable(Of Boolean)
|
||
Private _alreadyLoaded As Boolean
|
||
Private _parentWindow As Window
|
||
|
||
''' <summary>
|
||
''' Get/Set IsTopmost
|
||
''' </summary>
|
||
Public Property IsTopmost() As Boolean
|
||
Get
|
||
Return CBool(GetValue(IsTopmostProperty))
|
||
End Get
|
||
Set(value As Boolean)
|
||
SetValue(IsTopmostProperty, value)
|
||
End Set
|
||
End Property
|
||
|
||
''' <summary>
|
||
''' ctor
|
||
''' </summary>
|
||
Public Sub New()
|
||
' Chiamata richiesta dal Wpf
|
||
InitializeComponent()
|
||
'AddHandler Me.Loaded, AddressOf OnPopupLoaded
|
||
'AddHandler Me.Unloaded, AddressOf OnPopupUnloaded
|
||
End Sub
|
||
|
||
|
||
'Private Sub OnPopupLoaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
|
||
' If _alreadyLoaded Then
|
||
' Return
|
||
' End If
|
||
|
||
' _alreadyLoaded = True
|
||
|
||
' If Child IsNot Nothing Then
|
||
' Child.[AddHandler](PreviewMouseLeftButtonDownEvent, New MouseButtonEventHandler(AddressOf OnChildPreviewMouseLeftButtonDown), True)
|
||
' End If
|
||
|
||
' _parentWindow = Window.GetWindow(Me)
|
||
|
||
' If _parentWindow Is Nothing Then
|
||
' Return
|
||
' End If
|
||
|
||
' AddHandler _parentWindow.Activated, AddressOf OnParentWindowActivated
|
||
' AddHandler _parentWindow.Deactivated, AddressOf OnParentWindowDeactivated
|
||
|
||
'End Sub
|
||
|
||
'Private Sub OnPopupUnloaded(sender As Object, e As RoutedEventArgs) Handles Me.Unloaded
|
||
' If _parentWindow Is Nothing Then
|
||
' Return
|
||
' End If
|
||
' RemoveHandler _parentWindow.Activated, AddressOf OnParentWindowActivated
|
||
' RemoveHandler _parentWindow.Deactivated, AddressOf OnParentWindowDeactivated
|
||
|
||
'End Sub
|
||
|
||
'Private Sub OnParentWindowActivated(sender As Object, e As EventArgs)
|
||
' Debug.WriteLine("Parent Window Activated")
|
||
' SetTopmostState(True)
|
||
'End Sub
|
||
|
||
'Private Sub OnParentWindowDeactivated(sender As Object, e As EventArgs)
|
||
' Debug.WriteLine("Parent Window Deactivated")
|
||
|
||
' If IsTopmost = False Then
|
||
' SetTopmostState(IsTopmost)
|
||
' End If
|
||
'End Sub
|
||
|
||
'Private Sub OnChildPreviewMouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs)
|
||
' Debug.WriteLine("Child Mouse Left Button Down")
|
||
|
||
' SetTopmostState(True)
|
||
|
||
' If Not _parentWindow.IsActive AndAlso IsTopmost = False Then
|
||
' _parentWindow.Activate()
|
||
' Debug.WriteLine("Activating Parent from child Left Button Down")
|
||
' End If
|
||
'End Sub
|
||
|
||
Private Shared Sub OnIsTopmostChanged(obj As DependencyObject, e As DependencyPropertyChangedEventArgs)
|
||
Dim thisobj = DirectCast(obj, EgtPopup)
|
||
|
||
thisobj.SetTopmostState(thisobj.IsTopmost)
|
||
End Sub
|
||
|
||
Protected Overrides Sub OnOpened(e As EventArgs)
|
||
SetTopmostState(IsTopmost)
|
||
MyBase.OnOpened(e)
|
||
End Sub
|
||
|
||
Private Sub SetTopmostState(isTop As Boolean)
|
||
' Don’t apply state if it’s the same as incoming state
|
||
If _appliedTopMost.HasValue AndAlso _appliedTopMost = isTop Then
|
||
Return
|
||
End If
|
||
|
||
If Child Is Nothing Then
|
||
Return
|
||
End If
|
||
|
||
Dim hwndSource = TryCast(PresentationSource.FromVisual(Child), HwndSource)
|
||
|
||
If hwndSource Is Nothing Then
|
||
Return
|
||
End If
|
||
Dim hwnd = hwndSource.Handle
|
||
|
||
Dim rect As WinApi.RECT
|
||
|
||
If Not WinApi.GetWindowRect(hwnd, rect) Then
|
||
Return
|
||
End If
|
||
|
||
Debug.WriteLine("setting z-order " & isTop)
|
||
|
||
If isTop Then
|
||
WinApi.SetWindowPos(hwnd, WinApi.HWND_TOPMOST, 0, 0, 0, 0, _
|
||
WinApi.TOPMOST_FLAGS)
|
||
Else
|
||
' Z-Order would only get refreshed/reflected if clicking the
|
||
' the titlebar (as opposed to other parts of the external
|
||
' window) unless I first set the popup to HWND_BOTTOM
|
||
' then HWND_TOP before HWND_NOTOPMOST
|
||
WinApi.SetWindowPos(hwnd, WinApi.HWND_BOTTOM, 0, 0, 0, 0, _
|
||
WinApi.TOPMOST_FLAGS)
|
||
WinApi.SetWindowPos(hwnd, WinApi.HWND_TOP, 0, 0, 0, 0, _
|
||
WinApi.TOPMOST_FLAGS)
|
||
WinApi.SetWindowPos(hwnd, WinApi.HWND_NOTOPMOST, 0, 0, 0, 0, _
|
||
WinApi.TOPMOST_FLAGS)
|
||
End If
|
||
|
||
_appliedTopMost = isTop
|
||
End Sub
|
||
|
||
End Class
|