PowerShell数据模板绑定语法

3

我在使用PowerShell进行ItemsControl数据绑定时遇到了语法问题。下面是一个简单的WPF脚本,其中包含两个具有数据模板的itemscontrol示例。第一个示例(list01)拥有多个元素并且显示不正常,而第二个itemscontrol(list02)只有一个绑定元素,并且可以正常工作。

我正在寻找正确的语法来将对象绑定到第一个itemscontrol(list01)。

完整的PowerShell脚本(:

[xml]$xaml = @'

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="MainWindow"
        Title="ItemsControlDataBindingSample" Height="350" Width="300">
<Grid Margin="10">
    <Grid.RowDefinitions>
        <RowDefinition MinHeight="20"/>
        <RowDefinition MinHeight="50"/>
        <RowDefinition MinHeight="50"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="50"/>
    </Grid.ColumnDefinitions>

    <ItemsControl Name="LIST01" Grid.Row="1">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Margin="5">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="100" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Title}" />
                    <ProgressBar Grid.Column="1" Minimum="0" Maximum="100" Value="{Binding Completion}" />
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

    <ItemsControl Name="LIST02" Grid.Row="2">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Margin="5">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Label Content="{Binding}"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

    </Window>
    '@

#New-Object System.Windows.Controls.ItemsControl

[void][System.Reflection.Assembly]::LoadWithPartialName('PresentationFramework')
[void][reflection.assembly]::LoadWithPartialName('System.Drawing')

#Read XAML
$Form = [Windows.Markup.XamlReader]::Load( (New-Object System.Xml.XmlNodeReader $xaml) )

#Find objects
$MainWindow = $Form.FindName('MainWindow')
$List01 = $Form.FindName('LIST01')
$List02 = $Form.FindName('LIST02')

## this does not work ##
$Source01 = @(
    [ordered]@{ Title=([string]'Complete this WPF tutorial'); Completion=([int]45) },
    [ordered]@{ Title=([string]'Learn C#'); Completion=([int]80) },
    [ordered]@{ Title=([string]'Wash the car'); Completion=([int]25) }
    [ordered]@{ Title=([string]'Make KIDS do homework'); Completion=([int]3) }
);
## this does not work ##
$Source01 = @{ title='test01'; completion=50 }

## this does not work ##
$testArray = @()
$tmpObject = Select-Object -InputObject "" Title,Completion
$tmpObject.Title = 'Complete this WPF tutorial'
$tmpObject.Completion = 45
$testArray += $tmpObject

$List01.ItemsSource = $testArray
#$List01 | gm -type method


## this WORKS ##
$Source02 = @('TEST01','TEST02','TEST03')
$List02.ItemsSource = $Source02

[void]$Form.ShowDialog();

这段代码基于一个非常简单的C#示例:http://www.wpf-tutorial.com/list-controls/itemscontrol 但是,我不确定该语法如何直接转换为PowerShell。
1个回答

4

我建议使用MVVM模式。只需设置窗口的DataContext属性,然后将ItemsControl.ItemsSource属性绑定到您想要的列表,例如:ItemsSource="{Binding MyItemsListProperty}"

以下是一个完整的示例(基于您上面发布的示例代码):

$xaml = @"
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="MainWindow"
        Title="ItemsControlDataBindingSample" Height="350" Width="300">
<Grid Margin="10">

    <ItemsControl ItemsSource="{Binding MyItemsListProperty}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Margin="5">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="100" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Title}" />

                    <ProgressBar Grid.Column="1" Minimum="0" Maximum="100" Value="{Binding Completion}" />
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

</Grid>
</Window>
"@

[void][System.Reflection.Assembly]::LoadWithPartialName('PresentationFramework')

#Read XAML
$window = [Windows.Markup.XamlReader]::Parse($xaml)

$viewModel = New-Object PSObject -Property @{
    MyItemsListProperty = @(    
        New-Object PSObject -Property @{ 
            Title='Complete this WPF tutorial'
            Completion=45.0 
        };    
        New-Object PSObject -Property @{ 
            Title='Learn C#'
            Completion=80.0 
        };    
        New-Object PSObject -Property @{ 
            Title='Wash the car'
            Completion=25.0
        };    
        New-Object PSObject -Property @{ 
            Title='Make KIDS do homework'
            Completion=3.0 
        };
    )
};

$window.DataContext = $viewModel

$window.ShowDialog()

我的代码中还有其他需要声明的内容吗?我遇到了绑定错误:使用 1 个参数调用“Parse”时引发异常:“根级别上的数据无效。第 1 行,位置 1。”
  • $window = [Windows.Markup.XamlReader]::Parse($xaml)
    • FullyQualifiedErrorId : XamlParseException
此对象上找不到属性“DataContext”。请验证该属性是否存在并且可以设置。
  • $window.DataContext = $viewModel
  • + CategoryInfo : InvalidOperation: (:) [] + FullyQualifiedErrorId : PropertyNotFound
- g1tch0
“Parse”错误是唯一有趣的错误,因为其他错误都源于无法解析。您确定已完全正确地复制了文本吗?我现在已经在四台不同的机器上尝试运行上述代码,分别使用三种不同的操作系统(Windows 8.1、Windows Server 2008 R2和Windows Server 2012)以及不同的PowerShell版本(v2和v4)。在所有这些尝试中,它都运行良好(只要我确保使用STA标志启动powershell会话,但如果缺少该标志,就不会出现您提到的错误消息)。 - Robert Westerlund
使用“1”个参数调用“Parse”时出现异常:“根级别的数据无效。第1行,第1个位置。” 位于第30行字符:1
  • $window = [Windows.Markup.XamlReader]::Parse($xaml)
  • + CategoryInfo : 未经处理的: (:) [], MethodInvocationException + FullyQualifiedErrorId : XamlParseException
- g1tch0
该对象上找不到属性“DataContext”。请验证该属性是否存在并且可以设置。 位于第53行字符1
  • $window.DataContext = $viewModel
  • + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : PropertyNotFound
- g1tch0
错过了您关于它在许多不同机器上运行的评论---这已经在使用PS4.0的Windows 8.1 Ent.机器上尝试过了...我会在其他一些机器上尝试并查看是否出现相同的错误...感谢您的帮助。 - g1tch0
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接