添加"输入"和"逃脱"关键按下Powershell WPF表格

时间:2016-10-01 15:10:15

标签: wpf powershell

我使用ISE-Sterioids模板创建一个简单的3字段WPF表单,要求三件事:
- ID
- 电子邮件
- 参考
使用“确定”和“取消”按钮时,我已成功使用这些字段,但我想加入"输入"提交表格和" Escape"取消表单,但我添加事件有困难。

我在这里尝试过与technet文章相似的代码;但由于这不是使用WPF,我认为我遗漏了一些东西

$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
{$x=$objTextBox.Text;$objForm.Close()}})

我的代码在这里:

#region XAML window definition
# Right-click XAML and choose WPF/Edit... to edit WPF Design
# in your favorite WPF editing tool

# Default Form Values
$123 = 'ID'
$toEmail = 'email address'
$ref = "ref"

$xaml = @'
<Window
   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" mc:Ignorable="d"
   MinWidth="200"
   Width ="400"
   SizeToContent="Height"
   Title="Proofing script"
   Topmost="True">
    <Grid Margin="10,2,10,10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <!-- <TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Margin="5">Please enter your details:</TextBlock> -->

        <TextBlock Grid.Column="0" Grid.Row="1" Margin="5"><Run Text="Number:"/></TextBlock>
        <TextBlock Grid.Column="0" Grid.Row="2" Margin="5"><Run Text="To Email :"/></TextBlock>
        <TextBlock Grid.Column="0" Grid.Row="3" Margin="5"><Run Text="Salesforce Ref:"/></TextBlock>
        <TextBox x:Name="TxtName" Grid.Column="1" Grid.Row="1" Margin="5"/>
        <TextBox x:Name="TxtEmail" Grid.Column="1" Grid.Row="2" Margin="5"/>
        <TextBox x:Name="ref" Grid.Column="1" Grid.Row="3" Margin="5"/>

        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,5,0,0" Grid.Row="4" Grid.ColumnSpan="2">
            <Button x:Name="ButOk" MinWidth="80" Height="22" Margin="5" Content="OK" />
            <Button x:Name="ButCancel" MinWidth="80" Height="22" Margin="5" Content="Cancel" IsCancel="True" />
        </StackPanel>
    </Grid>
</Window>
'@
#endregion

#region Code Behind
function Convert-XAMLtoWindow
{
  param
  (
    [Parameter(Mandatory)]
    [string]
    $XAML,

    [string[]]
    $NamedElement=$null,

    [switch]
    $PassThru
  )

  Add-Type -AssemblyName PresentationFramework

  $reader = [XML.XMLReader]::Create([IO.StringReader]$XAML)
  $result = [Windows.Markup.XAMLReader]::Load($reader)
  foreach($Name in $NamedElement)
  {
    $result | Add-Member NoteProperty -Name $Name -Value $result.FindName($Name) -Force
  }

  if ($PassThru)
  {
    $result
  }
  else
  {
    $null = $window.Dispatcher.InvokeAsync{
      $result = $window.ShowDialog()
      Set-Variable -Name result -Value $result -Scope 1
    }.Wait()
    $result
  }
}

function Show-WPFWindow
{
  param
  (
    [Parameter(Mandatory)]
    [Windows.Window]
    $Window
  )

  $result = $null
  $null = $window.Dispatcher.InvokeAsync{
    $result = $window.ShowDialog()
    Set-Variable -Name result -Value $result -Scope 1
  }.Wait()
  $result
}
#endregion Code Behind

#region Convert XAML to Window
$window = Convert-XAMLtoWindow -XAML $xaml -NamedElement 'ButCancel', 'ButOk', 'ref', 'TxtEmail', 'TxtName' -PassThru
#endregion

#region Define Event Handlers
# Right-Click XAML Text and choose WPF/Attach Events to
# add more handlers
$window.ButCancel.add_Click(
  {
    $window.DialogResult = $false  
  }
)


$window.ButOk.add_Click(
  {
    $window.DialogResult = $true
  }

)
#endregion Event Handlers

#region Manipulate Window Content
#$window.TxtName.Text = $env:username
$window.ref.Text = $ref
$window.TxtName.Text = $123
$window.TxtEmail.Text = $toEmail
$null = $window.TxtName.Focus()

#endregion

# Show Window
$result = Show-WPFWindow -Window $window

如果我使用ISE类固醇添加一个事件,我会得到类似的

$window.ButOk.add_KeyDown{
  # remove param() block if access to event information is not required
  param
  (
    [Parameter(Mandatory)][Object]$sender,
    [Parameter(Mandatory)][Windows.Input.KeyEventArgs]$e
  )

  # add event code here
}

3 个答案:

答案 0 :(得分:1)

使用按键事件可能有点棘手,因为它们取决于当前的UIFocus,因此您的按钮不会对任何keydown事件起作用,因为当您只编辑文本框时它不在当前的焦点范围内。由于您只打算使用这个简单的表单,我建议您在窗口中添加一个处理此事件的事件处理程序。所以你的代码背后的代码应该是这样的:

$window.add_KeyDown{
param
(
  [Parameter(Mandatory)][Object]$sender,
  [Parameter(Mandatory)][Windows.Input.KeyEventArgs]$e
)
if($e.Key == $Key.Return)
{
    $window.DialogResult = $true
}

if($e.Key -eq $Key.Escape)
{
    $window.DialogResult = $false
}    
}

答案 1 :(得分:0)

被接受的答案对我来说还行不通,但是它对我有很大帮助,所以我在这里回答。

我用https://poshgui.com/Editor做了一个简单的表格,在答案中添加了代码,并得到了错误消息:

System.Management.Automation.RuntimeException:无法找到类型[Windows.Input.KeyEventArgs]

我的TextBox元素获得了焦点,因此我为其创建了一个事件:

TextBoxSearchInput.Add_KeyDown{
        param ( 
            [Parameter(Mandatory)][Object]$sender,
            [Parameter(Mandatory)][System.Windows.Forms.KeyEventArgs]$e
        )
        if($e.Key -eq $Key.Return){
            $FormOkButton.PerformClick()
        }
        if($e.Key -eq $Key.Escape){
            $Form.close()
        }
    }

也许有比“ PerformClick”更好的方法,但是目前它可以工作。

答案 2 :(得分:0)

我知道这里的线程很旧,但是我对此也很满意:

Add-Type -AssemblyName System.Windows.Forms    
Add-Type -AssemblyName System.Drawing

# Build Form
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Any Name"
$Form.Size = New-Object System.Drawing.Size(700,150) #use any size
$Form.StartPosition = "CenterScreen" # I prefer this
$Form.Topmost = $true 


$form.KeyPreview = $true #This is the important part
$form.Add_KeyDown{
    param ( 
        [Parameter(Mandatory)][Object]$sender,
        [Parameter(Mandatory)][System.Windows.Forms.KeyEventArgs]$e
    )
    if($_.KeyCode -eq "Escape"){
        $Form.close()
    }
}