2017-02-17 18 views
0

Обычно XAML я использую для столбца сетки данных с кнопкой-то вроде этого:Добавить событие Click WPF DataGrid Button Колонка в PowerShell

<DataGridTemplateColumn Header="ButtonColumn"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <Button Click="Click_Handler">Do Something</Button> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 

При использовании XAML в Powershell однако Click = не может быть используются, насколько я знаю, как он бросает ошибку:

"Failed to create a 'Click' from the text 'ClickEvent'. 

Как я могу получить ссылку на объект кнопки во время выполнения, чтобы добавить обработчик событий нажмите? Или есть способ создать функцию в Powershell, которая может быть вызвана именем, указанным в обработчике событий XAML.

Предоставление объекту имя и с помощью

$window.FindName("<button name>") 

Не работает

Упрощенный пример графического интерфейса может быть собран:

[xml]$xaml = @' 
<Window 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     x:Name="Window" Title="Demo" WindowStartupLocation = "CenterScreen" 
     SizeToContent="WidthAndHeight" 
     ShowInTaskbar = "True"> 

    <StackPanel Orientation="Vertical" Name="msiStackPanel"> 
     <TextBlock Margin="20,20,20,20" HorizontalAlignment="Center" FontSize="14" FontWeight="Bold">List of Stuff</TextBlock> 
     <DataGrid Name="myGrid" ItemsSource="{Binding}"> 
      <DataGrid.Columns> 
       <DataGridTextColumn Header="Name" Binding="{Binding Name}"/> 
       <DataGridTemplateColumn Header="Launch"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <Button Name="x:launchButton">Launch</Button> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
      </DataGrid.Columns> 
     </DataGrid> 
     <Button Margin="20,20,20,20">Completed All Tests</Button> 
    </StackPanel> 
</Window> 
'@ 

# Set PowerShell variable for each named object in GUI 
Function Set-WpfVariables 
{ 
    param($children) 
    ForEach ($child in $children.Children) 
    { 
     Set-WpfVariables -Children $child 
     if (![String]::IsNullOrEmpty($child.Name)) 
     { 
      Write-Host "Set variable $($child.Name)" 
      Set-Variable -Name $child.Name -Value $child -Scope global 
     }  
    } 
} 

# Build Window 
$reader=(New-Object System.Xml.XmlNodeReader $xaml) 
$Window=[Windows.Markup.XamlReader]::Load($reader) 

$controls = [System.Windows.LogicalTreeHelper]::GetChildren($window) 
Set-WpfVariables -Children $controls 

$table = New-Object System.Data.DataTable 
$table.Columns.Add("Name") 
$table.Rows.Add("Row 1") 
$table.Rows.Add("Row 2") 

$myGrid.DataContext = $table.DefaultView 

$window.ShowDialog() 

ответ

1

Вот рабочий скрипт для anyb ody заинтересован:

[xml]$xaml = @' 
<Window 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     x:Name="Window" Title="Demo" WindowStartupLocation = "CenterScreen" 
     SizeToContent="WidthAndHeight" 
     ShowInTaskbar = "True"> 

    <StackPanel Orientation="Vertical" Name="msiStackPanel"> 
     <TextBlock Margin="20,20,20,20" HorizontalAlignment="Center" FontSize="14" FontWeight="Bold">List of Stuff</TextBlock> 
     <DataGrid Name="myGrid" ItemsSource="{Binding}"> 
      <DataGrid.Columns> 
      </DataGrid.Columns> 
     </DataGrid> 
     <Button Margin="20,20,20,20">Completed All Tests</Button> 
    </StackPanel> 
</Window> 
'@ 

# Set PowerShell variable for each named object in GUI 
Function Set-WpfVariables 
{ 
    param($children) 
    ForEach ($child in $children.Children) 
    { 
     Set-WpfVariables -Children $child 
     if (![String]::IsNullOrEmpty($child.Name)) 
     { 
      Write-Host "Set variable $($child.Name)" 
      Set-Variable -Name $child.Name -Value $child -Scope global 
     }  
    } 
} 

# Build Window 
$reader=(New-Object System.Xml.XmlNodeReader $xaml) 
$Window=[Windows.Markup.XamlReader]::Load($reader) 

$controls = [System.Windows.LogicalTreeHelper]::GetChildren($window) 
Set-WpfVariables -Children $controls 

$table = New-Object System.Data.DataTable 
$table.Columns.Add("Name") 
$table.Rows.Add("Row 1") 
$table.Rows.Add("Row 2") 
$table.Rows.Add("Row 3") 


#$myGrid.DataContext = $table.DefaultView #This did not work for me. so... 
$myGrid = $window.FindName("myGrid") 
$myGrid.ItemsSource = $table.DefaultView 


[System.Windows.RoutedEventHandler]$clickEvent = { 
param ($sender,$e) 
    Write-Host "Clicked row $($myGrid.SelectedItem.Row.Name)" 
} 

$buttonColumn = New-Object System.Windows.Controls.DataGridTemplateColumn 
$buttonFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.Button]) 
$buttonFactory.SetValue([System.Windows.Controls.Button]::ContentProperty, "Launch") 
$buttonFactory.AddHandler([System.Windows.Controls.Button]::ClickEvent,$clickEvent) 
$dataTemplate = New-Object System.Windows.DataTemplate 
$dataTemplate.VisualTree = $buttonFactory 
$buttonColumn.CellTemplate = $dataTemplate 
$myGrid.Columns.Add($buttonColumn) 

$myGrid.DataContext = $table.DefaultView 

$window.ShowDialog() 
0

Установить имя, если вы хотите получить ссылка на кнопку:

<Button x:name="button" Click="Click_Handler">Do Something</Button> 

Затем в вашем коде позади вы можете использовать кнопку «.

button.Click += Click_Handler 

Я нахожу вашу ошибку нечетной, делает ли короткий пример, который вы опубликовали, причиной ошибки? Можете ли вы опубликовать код, где вы создаете свой Click_Handler?

+0

Да, это будет легко работать на C#, но в PowerShell. Я не уверен, как это будет достигнуто. Добавлен полный пример. –

1

В PowerShell, простейшем способе связывания событий, после анализа XAML.

Этот пример, из this site дает очень простой, но полный пример:

[xml]$xaml = @" 
<Window 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
x:Name="Window" 
Title="Blend and PowerShell" 
Width="640" Height="480" AllowsTransparency="False"> 
<Grid x:Name="LayoutRoot"> 
    <Rectangle Margin="22,8,22,0" VerticalAlignment="Top" Height="178" Stroke="#FF000000"> 
    <Rectangle.Fill> 
    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
    <GradientStop Color="#FF000000" Offset="0"/> 
    <GradientStop Color="#FF861A1A" Offset="1"/> 
    </LinearGradientBrush> 
    </Rectangle.Fill> 
    </Rectangle> 
    <Button Margin="121,0,129,96" VerticalAlignment="Bottom" Height="100" Content="Button" 
    x:Name="Close"/> 
</Grid> 
</Window> 
"@ 

# create an xml reader, then load the xaml 
$reader = New-Object System.Xml.XmlNodeReader $xaml 
$d = [Windows.Markup.XamlReader]::Load($reader) 

# find the button by name, then add a click event to it (which closes the window). 
$d.FindName("Close").add_click({ 
    $d.Close() 
}) 

# show the wpf window 
$d.ShowDialog() | out-null 
+1

Да, я знаю об использовании имени find, но это не находит объект кнопки в шаблоне столбца сетки данных, даже если я даю ему имя –

+0

Добавление рабочего примера –

0

Создание колонки кнопки программно, позволяет установить обработчик события:

[System.Windows.RoutedEventHandler]$clickEvent = { 
param ($sender,$e) 

    Write-Host "Clicked row $($myGrid.SelectedItem.Row.Name)" 
} 

$buttonColumn = New-Object System.Windows.Controls.DataGridTemplateColumn 
$buttonFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.Button]) 
$buttonFactory.SetValue([System.Windows.Controls.Button]::ContentProperty, "Launch") 
$buttonFactory.AddHandler([System.Windows.Controls.Button]::ClickEvent,$clickEvent) 
$dataTemplate = New-Object System.Windows.DataTemplate 
$dataTemplate.VisualTree = $buttonFactory 
$buttonColumn.CellTemplate = $dataTemplate 
$myGrid.Columns.Add($buttonColumn) 

$myGrid.DataContext = $table.DefaultView 

$window.ShowDialog() 

Для столбца, уже существует:

$buttonFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.Button]) 
$buttonFactory.SetValue([System.Windows.Controls.Button]::ContentProperty, "Launch") 
$buttonFactory.AddHandler([System.Windows.Controls.Button]::ClickEvent,$clickEvent) 
$dataTemplate = New-Object System.Windows.DataTemplate 
$dataTemplate.VisualTree = $buttonFactory 
$myGrid.Columns[1].CellTemplate = $dataTemplate