【问题标题】:How can I attach an event handler to a Button in a DataGridTemplateColumn defined in XAML, in PowerShell?如何在 PowerShell 中将事件处理程序附加到 XAML 中定义的 DataGridTemplateColumn 中的按钮?
【发布时间】:2014-08-01 22:20:02
【问题描述】:

我将一些 XAML 导入到 PowerShell 脚本中。它包含一个 DataGrid,它显示 PowerShell cmdlet 的结果。我使用DataGridTemplateColumn 为每一行添加了一个“编辑”按钮。现在,我想为每个按钮添加一个事件处理程序。我可以在代码中做到这一点:

$adUsersList_Results = $activeDirectory_Users_ListControl.FindName('ResultsDataGrid')
$dataTemplate = New-Object 'Windows.DataTemplate'
$buttonElement = New-Object 'Windows.FrameworkElementFactory' ([Windows.Controls.Button])
$buttonElement.SetValue([Windows.Controls.Button]::ContentProperty, "Edit")
$buttonElement.AddHandler([Windows.Controls.Button]::ClickEvent, [Windows.RoutedEventHandler]{
    PARAM (
        [Object]$sender,
        [Windows.RoutedEventArgs]$e
    )
    Write-Host "Clickety-click!"
    Write-Host $sender.DataContext
})
$dataTemplate.VisualTree = $buttonElement
$dataGridTemplateColumn = New-Object 'Windows.Controls.DataGridTemplateColumn'
$dataGridTemplateColumn.Header = 'Poo'
$dataGridTemplateColumn.CellTemplate = $dataTemplate
$adUsersList_Results.Columns.Add($dataGridTemplateColumn)

但它有点笨拙。 XAML 如下所示:

<DataGrid Grid.Row="1"
          x:Name="ResultsDataGrid"
          IsReadOnly="True"
          HorizontalAlignment="Stretch"
          Margin="3"
          VerticalAlignment="Stretch">
  <DataGrid.Columns>
    <DataGridTemplateColumn>
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <Button Content="Edit" Width="60" x:Name="ADUserListButton"/>
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
  </DataGrid.Columns>
</DataGrid>

我尝试过使用 FindName('ADUserListButton') 但它不起作用。有没有办法将所有视觉内容保留在 XAML 中,而只在 PowerShell 中执行事件处理程序?

旁白:我知道 Show-UI。在决定哪个最适合我们之前,我实际上在 Show-UI 和 PowerShell 和 XAML 中做同样的事情。

我也知道您可以在网格中进行编辑,但我认为对于此类数据而言,这不是很好的用户体验。

【问题讨论】:

    标签: wpf xaml powershell datagrid powershell-4.0


    【解决方案1】:

    我不太确定,但可能是因为您列出的 XAML 按钮没有与它的处理程序连接?即

    <Button Content="Edit" Width="60" x:Name="ADUserListButton" Click="ADUserListButton_Click"/>
    

    【讨论】:

    • 据我了解,ADUserListButton_Click 必须是代码隐藏文件中的事件处理程序。在 PowerShell 中使用动态 XAML 时,没有代码隐藏文件。相反,您可以像在代码中、在代码隐藏中那样连接事件处理程序,但您必须调用控件上的 Add_Click 方法,而不是使用 += 语法。
    【解决方案2】:

    我还没有使用 powershell 做到这一点,但如果它位于用户控件的 .cs 代码隐藏文件中,您可以尝试 GetTemplateChild("your control name")。

    【讨论】:

      【解决方案3】:

      以下是使用 Powershell 在数据网格中调用按钮的示例,希望对您有所帮助。

      Add-Type -AssemblyName PresentationFramework
      
      Function Check-Event($ev,$co,$da){
      $comp=$co.trim()
      $re = Get-EventLog Application -ComputerName "$comp" -InstanceId $ev -After $da
      $res.Text += "There are "+$re.count+" events pf EventID $ev on Computer $Comp after the time $da ch"
      }
      
      [Xml]$Form = @"
        <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      
              Title="MainWindow" Height="350" Width="525">
          <Grid>
              <DataGrid HorizontalAlignment="Left" Height="151" Margin="112,35,0,0" VerticalAlignment="Top" Width="279"/>
              <Button Name="ADUserListButton" Content="Edit" HorizontalAlignment="Left" Margin="140,85,0,0" VerticalAlignment="Top" Width="75"/>
              <TextBox Name="Result" HorizontalAlignment="Left" Height="23" Margin="140,124,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="Hello World"/>
          </Grid>
      </Window>
      
      "@
      
      $NR=(New-Object System.Xml.XmlNodeReader $Form)
      $Win=[Windows.Markup.XamlReader]::Load( $NR )
      
      $Start = $Win.FindName("ADUserListButton")
      $res = $Win.FindName("Result")
      
      $Start.Add_Click({
      $event=$res.text
      If($event -eq "") {
      [System.Windows.MessageBox]::Show("Please make sure all values are entered", "Missing Values")} 
      Else{Get-WMIObject -class Win32_ComputerSystem | select username -OutVariable a
      $name=$a.username
      [System.Windows.MessageBox]::Show("User name is $name", "Hello")
      }
      })
      

      【讨论】:

        【解决方案4】:

        我对列出大量数据的网格单击所做的事情,而不是为每个单元格创建代码,您可以在数据网格上创建一个单击处理程序,以获取选定的行或单元格并对其进行处理。

        $adUsersList_Results = $activeDirectory_Users_ListControl.FindName('ResultsDataGrid')
        $adUsersList.Add_Click({
          $sender = $args[0]
          $e      = $args[1]
          $prop = $sender.SelectedItem.<#[Some property of the row]#>
          #do something with $prop....
        })
        

        不知道这是否是你要找的,我知道这有点晚了,但它可能会帮助其他人......

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-12
          • 2012-10-23
          • 1970-01-01
          • 2011-05-12
          相关资源
          最近更新 更多