XAML 如何在WPF中同步子窗口的大小以匹配父窗口

owfi6suc  于 2023-06-19  发布在  其他
关注(0)|答案(1)|浏览(181)

我在WPF中有一个MainWindow,它创建了另一个窗口(Window1),并使用user32.dll中的SetParent将MainWindow设置为Window1的父窗口。
这是我的主窗口代码

Class MainWindow

Dim Window1 As Window1

    Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Me.Left = 0
        Me.Top = 0
        Window1 = New Window1(New Interop.WindowInteropHelper(Me).Handle)
        Window1.Show()
    End Sub

    Private Sub Window_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles Me.SizeChanged
        If Window1 IsNot Nothing Then
            Window1.Width = Me.ActualWidth
            Window1.Height = Me.ActualHeight
        End If
    End Sub
End Class

这是我的MainWindow XAML代码

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_01"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" Background="Cyan"
        AllowsTransparency="True" WindowStyle="None" ResizeMode="CanResizeWithGrip">
</Window>

这是我的Windows1代码

Public Class Window1

    Sub New(parentWindowHandle As IntPtr)
        InitializeComponent()
        Dim interop = New Interop.WindowInteropHelper(Me)
        interop.EnsureHandle()
        Me.WindowStartupLocation = WindowStartupLocation.Manual
        Me.Left = 0
        Me.Top = 0
        SetParent(interop.Handle, parentWindowHandle)
    End Sub
    Public Declare Function SetParent Lib "user32" (hWndChild As IntPtr, hWndNewParent As IntPtr) As IntPtr
End Class

这是我的Windows1 XAML代码

<Window x:Class="Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_01"
        mc:Ignorable="d"
        Title="Window1" Height="300" Width="300" Background="Magenta" 
        WindowStyle="None" AllowsTransparency="True">
</Window>

当我运行示例代码并调整MainWindow的大小时,Window1也会调整大小。Window1大小与MainWindow大小匹配。
这是正确的行为。但如果主窗口有不同的位置,如:

Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Me.Left = 10
        Me.Top = 0
        Window1 = New Window1(New Interop.WindowInteropHelper(Me).Handle)
        Window1.Show()
    End Sub

调整MainWindow的大小会导致Window1也向右侧移动。
这种行为是不正确的。当MainWindow和Window1的AllowsTransparency参数设置为False时,会发生此行为。如何调整Window1的大小以使其与主窗口的大小相匹配?
编辑:这里是一个视频展示项目代码在visual studio,只是让我们清楚的代码,这是在net framework 4.6.2. https://www.veed.io/view/6ef01c2a-73d6-42e0-80fd-8ae096e96b4f
这是Chrome代码,增加了移动带有不可见标题栏的主窗口的能力。

<WindowChrome.WindowChrome>
    <WindowChrome     
        CaptionHeight="10"  
        ResizeBorderThickness="4">
    </WindowChrome>
</WindowChrome.WindowChrome>

这里是一个调试的视频,正如你所看到的,当mainwindow位于0,0时,一切都很好,但是一旦我将mainwindow移动到不是0,0的位置,它就会导致子窗口移动和调整大小,但是没有添加代码来移动window1。https://www.veed.io/view/85db988b-fe22-4548-b92a-1761dd8a2508
这一个显示了改变窗口到allowtransparency ="false"给出了预期的行为,这意味着它可能与透明窗口的呈现方式有关。https://www.veed.io/view/77351d65-f769-4f84-8849-cd3127fee783

slmsl1lt

slmsl1lt1#

你可以在子窗口的构造函数中传递父窗口:

Public Class ChildWindow

    Private WithEvents _parentWindow As Window

    Public Sub New(parentWindow As Window)

        ' This call is required by the designer.
        InitializeComponent()

        ' Store reference
        _parentWindow = parentWindow

        ' Copy parentWindow's size
        With parentWindow
            Me.Height = .Height
            Me.Width = .Width
        End With

        ' Move Window to top left of the screen
        Me.WindowStartupLocation = WindowStartupLocation.Manual
        Me.Left = 0
        Me.Top = 0

    End Sub

    Private Sub _parentWindow_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles _parentWindow.SizeChanged
        ' Update Window's size to values in NewSize
        With e.NewSize
            Me.Height = .Height
            Me.Width = .Width
        End With
    End Sub

End Class

在这段代码中,我存储了一个parentWindow的引用,并处理它的SizeChanged事件,以便在parentWindow的大小改变时调整子窗口的大小。当MainWindow的位置改变时,子窗口的位置不会改变。将AllowsTransparency设置为False对此没有影响。

相关问题