[英]powershell wpf xaml treeview binding understanding
I have a script with a gui based on native WPF and XAML (from here: https://foxdeploy.com/functions/ise-snippets/xaml-to-gui/ ). 我有一个基于本地WPF和XAML的gui脚本(来自此处: https : //foxdeploy.com/functions/ise-snippets/xaml-to-gui/ )。 The hierarchical structure XAMl Code is from this tutorial: https://dlaa.me/blog/post/9898803 .
XAMl代码的分层结构来自于本教程: https ://dlaa.me/blog/post/9898803。 For now I try to figure out how should a pscustomobject should look like to pass it to "Binding SubItems".
现在,我尝试找出pscustomobject应该如何将其传递给“ Binding SubItems”。 How can I declare what is a parent item and whats a childitem?
如何声明什么是父项,什么是子项? I think its very easy but I can not get it.
我认为它很容易,但我无法理解。 I have read and tried a lot but can't find any native WPF examples.
我已经阅读并尝试了很多,但是找不到任何本地WPF示例。 Could anyone point me into the right direction.
谁能指出我正确的方向。 I appreciate any help.
感谢您的帮助。
$inputXML = @"
<Window x:Class="SimpleTreeGridUX.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SimpleTreeGridUX" Height="400" Width="400">
<Grid Margin="10">
<!-- TreeGrid "Control" -->
<Border BorderBrush="Black" BorderThickness="1">
<!-- Resources -->
<Border.Resources>
<Style x:Key="TextBlockStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="3 0 3 0"/>
</Style>
<Style x:Key="TextBlockBoldStyle" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource TextBlockStyle}">
<Setter Property="FontWeight" Value="Bold"/>
</Style>
</Border.Resources>
<!-- Content -->
<Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- Column headers -->
<TreeViewItem Grid.Row="0" BorderThickness="1">
<TreeViewItem.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Task"/>
<!-- Placeholders for two columns of ToggleButton -->
<ColumnDefinition SharedSizeGroup="Toggle"/>
<ColumnDefinition SharedSizeGroup="Toggle"/>
<ColumnDefinition SharedSizeGroup="Duration"/>
<ColumnDefinition SharedSizeGroup="Notes"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Task" Style="{StaticResource TextBlockBoldStyle}"/>
<!-- Empty TreeViewItem to measure the size of its ToggleButton into the "Toggle" group-->
<TreeViewItem Grid.Column="1" Padding="0"/>
<TextBlock Grid.Column="3" Text="Duration" Style="{StaticResource TextBlockBoldStyle}"/>
<TextBlock Grid.Column="4" Text="Notes" Style="{StaticResource TextBlockBoldStyle}"/>
</Grid>
</TreeViewItem.Header>
</TreeViewItem>
<!-- Data rows -->
<TreeView Grid.Row="1" x:Name="treeview" ItemsSource="{Binding SubItems}" BorderBrush="Gray" BorderThickness="0 1 0 0">
<TreeView.ItemTemplate>
<!-- Level 0 template leaves space for 2 child "Toggle" levels -->
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Task"/>
<ColumnDefinition SharedSizeGroup="Toggle"/>
<ColumnDefinition SharedSizeGroup="Toggle"/>
<ColumnDefinition SharedSizeGroup="Duration"/>
<ColumnDefinition SharedSizeGroup="Notes"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Task}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="3" Text="{Binding Duration}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="4" Text="{Binding Notes}" Style="{StaticResource TextBlockStyle}"/>
</Grid>
<!-- Level 1 template leaves space for 1 child "Toggle" level -->
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Task"/>
<ColumnDefinition/>
<ColumnDefinition SharedSizeGroup="Toggle"/>
<ColumnDefinition SharedSizeGroup="Duration"/>
<ColumnDefinition SharedSizeGroup="Notes"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Task}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="3" Text="{Binding Duration}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="4" Text="{Binding Notes}" Style="{StaticResource TextBlockStyle}"/>
</Grid>
<!-- Level 2 template has no children -->
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Task"/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition SharedSizeGroup="Duration"/>
<ColumnDefinition SharedSizeGroup="Notes"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Task}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="3" Text="{Binding Duration}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="4" Text="{Binding Notes}" Style="{StaticResource TextBlockStyle}"/>
</Grid>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</Border>
</Grid>
</Window>
"@
$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML
#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
catch [System.Management.Automation.MethodInvocationException] {
Write-Warning "We ran into a problem with the XAML code. Check the syntax for this control..."
write-host $error[0].Exception.Message -ForegroundColor Red
if ($error[0].Exception.Message -like "*button*"){
write-warning "Ensure your <button in the `$inputXML does NOT have a Click=ButtonClick property. PS can't handle this`n`n`n`n"}
}
catch{#if it broke some other way <img draggable="false" class="emoji" alt="😀" src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/svg/1f600.svg">
Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed."
}
#===========================================================================
# Store Form Objects In PowerShell
#===========================================================================
$xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name)}
Function Get-FormVariables{
if ($global:ReadmeDisplay -ne $true){Write-host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow;$global:ReadmeDisplay=$true}
write-host "Found the following interactable elements from our form" -ForegroundColor Cyan
get-variable WPF*
}
Get-FormVariables
#===========================================================================
# Use this space to add code to the various form elements in your GUI
#===========================================================================
$Data = @{
Task = "Main-Task";
Duration = "10";
Notes = "notes";
SubItems = @{
Task = "Task Ebene 2";
Duration = "20";
Notes = "notes2";
SubItems = @{
Task = "Task Ebene 3";
Duration = "30";
Notes = "notes3";
}
}
}
$Object = New-Object -TypeName PSObject -Property $Data
$WPFtreeview.items.Add($Object)
#Reference
#Adding items to a dropdown/combo box
#$vmpicklistView.items.Add([pscustomobject]@{'VMName'=($_).Name;Status=$_.Status;Other="Yes"})
#Setting the text of a text box to the current PC name
#$WPFtextBox.Text = $env:COMPUTERNAME
#Adding code to a button, so that when clicked, it pings a system
# $WPFbutton.Add_Click({ Test-connection -count 1 -ComputerName $WPFtextBox.Text
# })
#===========================================================================
# Shows the form
#===========================================================================
write-host "To show the form, run the following" -ForegroundColor Cyan
$Form.ShowDialog() | out-null
@snicz: Thank you very much for your answer, I don't know why your answer is disappeared, guess a technical problem from stackoverflow. @snicz:非常感谢您的回答,我不知道为什么您的答案消失了,请从stackoverflow猜测一个技术问题。 regarding your answer, you posted the code from David Anson's Project:
关于您的答案,您发布了David Anson项目的代码:
TreeViewItem ParentItem = new TreeViewItem();
ParentItem.Header = "Parent";
TreeView1.Items.Add(ParentItem);
//
TreeViewItem Child1Item = new TreeViewItem();
Child1Item.Header = "Child One";
ParentItem.Items.Add(Child1Item);
//
TreeViewItem Child2Item = new TreeViewItem();
Child2Item.Header = "Child Two";
ParentItem.Items.Add(Child2Item);
TreeViewItem SubChild1Item = new TreeViewItem();
SubChild1Item.Header = "Sub Child One";
Child2Item.Items.Add(SubChild1Item);
TreeViewItem SubChild2Item = new TreeViewItem();
SubChild2Item.Header = "Sub Child Two";
Child2Item.Items.Add(SubChild2Item);
TreeViewItem SubChild3Item = new TreeViewItem();
SubChild3Item.Header = "Sub Child Three";
Child2Item.Items.Add(SubChild3Item);
//
TreeViewItem Child3Item = new TreeViewItem();
Child3Item.Header = "Child Three";
ParentItem.Items.Add(Child3Item);
//
ParentItem.IsExpanded = true;
Child2Item.IsExpanded = true;
}
I also found this but I'm looking for a "powershell only" way, how would exactly this looks like if I create pscustomobject? 我也发现了这一点,但是我正在寻找一种“仅Powershell”方式,如果我创建pscustomobject的话,它将是什么样子? I also found some Windows Forms Examples but I would like to include it in a project thats only XAML and WPF/Powershell (like the Code in initial Question above).
我还找到了一些Windows窗体示例,但我想将其包含在仅XAML和WPF / Powershell的项目中(例如上述初始问题中的代码)。
I'm not sure if its clear what I'am talking about? 我不确定我在说什么吗?
got it working this way: Sure, there is a much shorter way, but it may help someone to understand it easier. 可以这样工作:当然,有一种更短的方法,但是它可以帮助人们更容易地理解它。
$inputXML = @"
<Window x:Class="SimpleTreeGridUX.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SimpleTreeGridUX" Height="400" Width="400">
<Grid Margin="10">
<!-- TreeGrid "Control" -->
<Border BorderBrush="Black" BorderThickness="1">
<!-- Resources -->
<Border.Resources>
<Style x:Key="TextBlockStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="3 0 3 0"/>
</Style>
<Style x:Key="TextBlockBoldStyle" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource TextBlockStyle}">
<Setter Property="FontWeight" Value="Bold"/>
</Style>
</Border.Resources>
<!-- Content -->
<Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- Column headers -->
<TreeViewItem Grid.Row="0" BorderThickness="1">
<TreeViewItem.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Task"/>
<!-- Placeholders for two columns of ToggleButton -->
<ColumnDefinition SharedSizeGroup="Toggle"/>
<ColumnDefinition SharedSizeGroup="Toggle"/>
<ColumnDefinition SharedSizeGroup="Duration"/>
<ColumnDefinition SharedSizeGroup="Notes"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Task" Style="{StaticResource TextBlockBoldStyle}"/>
<!-- Empty TreeViewItem to measure the size of its ToggleButton into the "Toggle" group-->
<TreeViewItem Grid.Column="1" Padding="0"/>
<TextBlock Grid.Column="3" Text="Duration" Style="{StaticResource TextBlockBoldStyle}"/>
<TextBlock Grid.Column="4" Text="Notes" Style="{StaticResource TextBlockBoldStyle}"/>
</Grid>
</TreeViewItem.Header>
</TreeViewItem>
<!-- Data rows -->
<TreeView Grid.Row="1" x:Name="treeview" ItemsSource="{Binding SubItems}" BorderBrush="Gray" BorderThickness="0 1 0 0">
<TreeView.ItemTemplate>
<!-- Level 0 template leaves space for 2 child "Toggle" levels -->
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Task"/>
<ColumnDefinition SharedSizeGroup="Toggle"/>
<ColumnDefinition SharedSizeGroup="Toggle"/>
<ColumnDefinition SharedSizeGroup="Duration"/>
<ColumnDefinition SharedSizeGroup="Notes"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Task}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="3" Text="{Binding Duration}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="4" Text="{Binding Notes}" Style="{StaticResource TextBlockStyle}"/>
</Grid>
<!-- Level 1 template leaves space for 1 child "Toggle" level -->
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Task"/>
<ColumnDefinition/>
<ColumnDefinition SharedSizeGroup="Toggle"/>
<ColumnDefinition SharedSizeGroup="Duration"/>
<ColumnDefinition SharedSizeGroup="Notes"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Task}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="3" Text="{Binding Duration}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="4" Text="{Binding Notes}" Style="{StaticResource TextBlockStyle}"/>
</Grid>
<!-- Level 2 template has no children -->
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Task"/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition SharedSizeGroup="Duration"/>
<ColumnDefinition SharedSizeGroup="Notes"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Task}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="3" Text="{Binding Duration}" Style="{StaticResource TextBlockStyle}"/>
<TextBlock Grid.Column="4" Text="{Binding Notes}" Style="{StaticResource TextBlockStyle}"/>
</Grid>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</Border>
</Grid>
</Window>
"@
$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML
#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
catch [System.Management.Automation.MethodInvocationException] {
Write-Warning "We ran into a problem with the XAML code. Check the syntax for this control..."
write-host $error[0].Exception.Message -ForegroundColor Red
if ($error[0].Exception.Message -like "*button*"){
write-warning "Ensure your <button in the `$inputXML does NOT have a Click=ButtonClick property. PS can't handle this`n`n`n`n"}
}
catch{#if it broke some other way <img draggable="false" class="emoji" alt="😀" src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/svg/1f600.svg">
Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed."
}
#===========================================================================
# Store Form Objects In PowerShell
#===========================================================================
$xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name)}
Function Get-FormVariables{
if ($global:ReadmeDisplay -ne $true){Write-host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow;$global:ReadmeDisplay=$true}
write-host "Found the following interactable elements from our form" -ForegroundColor Cyan
get-variable WPF*
}
Get-FormVariables
#===========================================================================
# Use this space to add code to the various form elements in your GUI
#===========================================================================
$Data=[pscustomobject]@{Task='Erster Haupteintrag';Duration="10";Notes="notes 1"}
$Child=[pscustomobject]@{Task="Zweite Ebene";Duration="20"; Notes="notes 22"}
$Data2=[pscustomobject]@{Task='Zweiter Haupteintrag';Duration="20";Notes="notes 2"; Subitems=@($Child)}
$Child3=[pscustomobject]@{Task="Dritte Ebene";Duration="35"; Notes="notes 3"}
$Child2=[pscustomobject]@{Task="Zweite Ebene 2";Duration="20"; Notes="notes 222"; Subitems=@($Child3)}
$Data3=[pscustomobject]@{Task='Dritter Haupteintrag';Duration="30";Notes="notes 3"; Subitems=@($Child2)}
$WPFtreeview.items.Add($Data)
$WPFtreeview.items.Add($Data2)
$WPFtreeview.items.Add($Data3)
#Reference
#Adding items to a dropdown/combo box
#$vmpicklistView.items.Add([pscustomobject]@{'VMName'=($_).Name;Status=$_.Status;Other="Yes"})
#Setting the text of a text box to the current PC name
#$WPFtextBox.Text = $env:COMPUTERNAME
#Adding code to a button, so that when clicked, it pings a system
# $WPFbutton.Add_Click({ Test-connection -count 1 -ComputerName $WPFtextBox.Text
# })
#===========================================================================
# Shows the form
#===========================================================================
write-host "To show the form, run the following" -ForegroundColor Cyan
$Form.ShowDialog() | out-null
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.