如果我通过$WPFdialog.Show()
从Powershell脚本中打开一个非模态对话框,窗口会出现,但不会对单击任务栏图标做出React。我希望它能够最小化并从那里恢复。如果我通过ShowDialog()
打开它,就没有问题。
我不想使用模态对话框,因为我需要GUI线程来检查后台任务活动。我的方法是在后台活动处理旁边调用DoEvents()
。这在调整窗口大小或关闭窗口时工作正常,但对话框不会对任务栏上的单击做出React。事实上,它似乎根本没有从任务栏接收WM_SYSCOMMAND SC_MINIMIZE消息,所以我不知道在哪里添加适当的事件处理程序。
感谢帮助。Windows 7 Powershell 5.1
示例脚本:
param( $ARG1, $ARG2, $ARG3, $ARG4 )
Add-Type -AssemblyName System.Windows.Forms
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
################### XAML-Code ###################
$inputXML = @"
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="Test App" Height="200" Width="300" ResizeMode="CanResize" WindowStartupLocation="CenterScreen">
<Grid>
<Label HorizontalAlignment="Center" VerticalAlignment="Center">Welcome</Label>
<Button x:Name="Close" Content="Close" HorizontalAlignment="Center" Margin="0,101,0,0" VerticalAlignment="Top"/>
</Grid>
</Window>
"@
############### Parse and use XAML ###############
$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'
[xml]$xaml = $inputXML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$WPFdialog=[Windows.Markup.XamlReader]::Load( $reader )
$xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name "WPF$($_.Name)" -Value $WPFdialog.FindName($_.Name)}
$WPFclose.Add_Click({
$WPFdialog.Close()
})
#$res = $WPFdialog.ShowDialog()
$res = $WPFdialog.Show()
do
{
[System.Windows.Forms.Application]::DoEvents()
# planned: handle some background progress here
Start-Sleep -Milliseconds 20
$hwnd = [Windows.PresentationSource]::FromVisual($WPFdialog)
}
while ($hwnd)
1条答案
按热度按时间6kkfgxo01#
你自己找到了一个务实的解决方案:
[System.Windows.Forms.Application]::DoEvents()
方法,以便保持窗口响应,因为WPF没有 * 等效的方法。[System.Threading.Thread]::Sleep()
而不是Start-Sleep
**。以上所述的代价是不得不加载WinForms程序集-尽管这在实践中可能不是问题。
请继续阅读,以获得仅WPF的解决方案。
一个纯WPF解决方案是可能的,即通过一个WPF模拟WinForms的
DoEvents()
的自定义实现 *,如DispatcherFrame
类的帮助主题所示,并在下面实现。同样,也必须使用
[System.Threading.Thread]::Sleep()
而不是Start-Sleep
。相比之下,我在我的Windows 11 22H2(ARM)虚拟机上看不到这个,无论是在Windows PowerShell www.example.com(. NET Framework 4.8.9166.0)还是在PowerShell Core v7.4.0-preview.3(. NET 8.0.0-preview.3.23174.8)中:v5.1.22621.1778 (.NET Framework 4.8.9166.0) nor in PowerShell Core v7.4.0-preview.3 (.NET 8.0.0-preview.3.23174.8):
DoWpfEvents
无法调度WM_PAINT
消息,如果窗口是不活动的,并在前台窗口,以便当前台窗口得到关闭(仍然不活动!)对话框需要重绘。DoEvents
似乎处理得很好。(我的附录,Yacc)这就是在Win 7上使用DoWpfEvents调度的方式。DoEvents工作正常。唯一的区别是WM_PAINT(消息代码15)丢失。