首页 > 解决方案 > Powershell、XAML、WPF - ListView 分组不起作用

问题描述

我需要帮助以了解为什么在下面的示例中未对列表项进行分组。

“属性”和“价值”数据正在填充,但根本没有分组。我从在线示例中拼凑出这个脚本,但并没有真正了解 XAML 以及数据绑定的工作原理等,以及它应该如何在 PowerShell 上下文中工作。它工作正常,但我重构了代码并且分组功能坏了,现在我无法弄清楚为什么。

如果有人可以帮助我,将不胜感激。

模态窗口.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"
        xmlns:local="clr-namespace:WpfApp2"
        Title="Confirm User Details" Height="580" Width="360" >

    <Grid Margin="10">
        <ListView Name="DataListView" Margin="0" VerticalAlignment="Top" Height="475">
            <ListView.Resources>
                <Style TargetType="GridViewColumnHeader">
                    <Setter Property="Visibility" Value="Collapsed" />
                </Style>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="110" DisplayMemberBinding="{Binding Property}" />
                    <GridViewColumn Width="196" DisplayMemberBinding="{Binding Value}" />
                </GridView>
            </ListView.View>

            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock Margin="5" TextDecorations="Underline" FontSize="13" Text="{Binding Name}"/>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </ListView.GroupStyle>
        </ListView>
        <Button Name="ConfirmButton" Content="OK" Height="39" Width="160" HorizontalAlignment="Left" VerticalAlignment="Bottom"  />
        <Button Name="CancelButton" Content="Cancel" Margin="0" Width="160" Height="39" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
    </Grid>

   </Window>

主要.ps1

Function GetListViewItemsSource() {

   Param ($NewADUserParams)

   $Data = @()

   $Groupings = @{
       DEFAULT      = "Other";
       GENERAL      = "General";
       ACCOUNT      = "Account";
       ORGANIZATION = "Organization";
   }

   $IgnoredKeys = @("PassThru", "Enabled")

   $GroupingsMap = @{
       Description           = $Groupings.GENERAL;
       UserPrincipalName     = $Groupings.ACCOUNT;
       DisplayName           = $Groupings.GENERAL;
       SamAccountName        = $Groupings.ACCOUNT;
       AccountExpirationDate = $Groupings.ACCOUNT;
       Name                  = $Groupings.GENERAL;
       Company               = $Groupings.ORGANIZATION;
   }

   ForEach ($Key in $NewADUserParams.Keys) {

       If ($IgnoredKeys -contains $Key) { Continue; }

       $Grouping = $Groupings.DEFAULT

       If ($GroupingsMap.ContainsKey($Key)) {
           $Grouping = $GroupingsMap[$Key]
       }

       $Data += New-Object PSObject -prop @{Property = $Key; Value = $NewADUserParams[$Key]; Grouping = $Grouping; }

   }

   $ListViewItemsSource = [System.Windows.Data.ListCollectionView] $Data
   $ListViewItemsSource.GroupDescriptions.Add((New-Object System.Windows.Data.PropertyGroupDescription "Grouping"))


   Return $ListViewItemsSource
}


Function ShowModalWindow() {

   Param ($ListViewItemsSource)

   [XML] $ModalWindowXAML = Get-Content -Path $Config.XAML.ModalWindow

   $NodeReader = (New-Object System.Xml.XmlNodeReader $ModalWindowXAML)
   $ModalWindow = [Windows.Markup.XamlReader]::Load( $NodeReader )

   $ListView = $ModalWindow.FindName("DataListView")
   $ListView.ItemsSource = $ListViewItemsSource

   $ConfirmButton = $ModalWindow.FindName("ConfirmButton")
   $CancelButton = $ModalWindow.FindName("CancelButton")

   $Response = @{
       Value = 0
   }

   $ConfirmButton.Add_Click( {
        $Response.Value = 1
        $ModalWindow.Close()
    })

   $CancelButton.Add_Click( {
        $ModalWindow.Close()
    })

   $ModalWindow.ShowDialog()

   Return $Response

}

$NewADUserParams = @{
   # ...
   Description = "bar, foo";
   DisplayName = "bar, foo";
   SamAccountName = "foo.bar";
   AccountExpirationDate = "12/31/9999 00:00:00";
   Name = "foo.bar";
   GivenName = "foo";
   Title = boss;
   OtherAttributes = System.Collections.Hashtable;
   Surname = "bar";
   ChangePasswordAtLogon = True;
   # etc...
}
$ListViewItemsSource = GetListViewItemsSource -NewADUserParams $NewADUserParams
$ConfirmUserProps = ShowModalWindow -ListViewItemsSource $ListViewItemsSource

结果模态对话框

输出

编辑

为了澄清,这就是我想要实现的目标:

在此处输入图像描述

请参阅:https ://www.wpf-tutorial.com/listview-control/listview-grouping/

标签: wpfpowershellxaml

解决方案


当我剪切并粘贴您的代码并纠正一些问题时(只是 $NewADUserParams 中的内容,例如 = "boss" 而不是 = boss),以便它将在我的机器上运行,所有内容都被分组 - 尽管它并不那么花哨。所有将军都在一起,等等。我添加了一个显示分组的列,这样更容易看到。

如果您注释掉 $ListViewItemsSource.GroupDescriptions.Add((New-Object System.Windows.Data.PropertyGroupDescription "Grouping"))

您应该按照添加的顺序查看数据,而不是组合在一起。

Function GetListViewItemsSource() {

   Param ($NewADUserParams)

   $Data = @()

   $Groupings = @{
       DEFAULT      = "Other";
       GENERAL      = "General";
       ACCOUNT      = "Account";
       ORGANIZATION = "Organization";
   }

   $IgnoredKeys = @("PassThru", "Enabled")

   $GroupingsMap = @{
       Description           = $Groupings.GENERAL;
       UserPrincipalName     = $Groupings.ACCOUNT;
       DisplayName           = $Groupings.GENERAL;
       SamAccountName        = $Groupings.ACCOUNT;
       AccountExpirationDate = $Groupings.ACCOUNT;
       Name                  = $Groupings.GENERAL;
       Company               = $Groupings.ORGANIZATION;
   }

   ForEach ($Key in $NewADUserParams.Keys) {

       If ($IgnoredKeys -contains $Key) { Continue; }

       $Grouping = $Groupings.DEFAULT

       If ($GroupingsMap.ContainsKey($Key)) {
           $Grouping = $GroupingsMap[$Key]
       }

       $Data += New-Object PSObject -prop @{Property = $Key; Value = $NewADUserParams[$Key]; Grouping = $Grouping; }

   }

   $ListViewItemsSource = [System.Windows.Data.ListCollectionView] $Data
   $ListViewItemsSource.GroupDescriptions.Add((New-Object System.Windows.Data.PropertyGroupDescription "Grouping"))


   Return $ListViewItemsSource
}


Function ShowModalWindow() {

   Param ($ListViewItemsSource)

   [XML] $ModalWindowXAML = Get-Content -Path C:\Users\mspow\OneDrive\Documents\ModalWindow.xml

   $NodeReader = (New-Object System.Xml.XmlNodeReader $ModalWindowXAML)
   $ModalWindow = [Windows.Markup.XamlReader]::Load( $NodeReader )

   $ListView = $ModalWindow.FindName("DataListView")
   $ListView.ItemsSource = $ListViewItemsSource

   $ConfirmButton = $ModalWindow.FindName("ConfirmButton")
   $CancelButton = $ModalWindow.FindName("CancelButton")

   $Response = @{
       Value = 0
   }

   $ConfirmButton.Add_Click( {
        $Response.Value = 1
        $ModalWindow.Close()
    })

   $CancelButton.Add_Click( {
        $ModalWindow.Close()
    })

   $ModalWindow.ShowDialog()

   Return $Response

}

$NewADUserParams = @{
   # ...
   Description = "bar, foo";
   DisplayName = "bar, foo";
   SamAccountName = "foo.bar";
   AccountExpirationDate = "12/31/9999 00:00:00";
   Name = "foo.bar";
   GivenName = "foo";
   Title = 'boss';
   OtherAttributes = 'System.Collections.Hashtable';
   Surname = "bar";
   ChangePasswordAtLogon = $true;
   # etc...
}
$ListViewItemsSource = GetListViewItemsSource -NewADUserParams $NewADUserParams
$ConfirmUserProps = ShowModalWindow -ListViewItemsSource $ListViewItemsSource
<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"
        xmlns:local="clr-namespace:WpfApp2"
        Title="Confirm User Details" Height="580" Width="360" >

    <Grid Margin="10">
        <ListView Name="DataListView" Margin="0" VerticalAlignment="Top" Height="475">
            <ListView.Resources>
                <Style TargetType="GridViewColumnHeader">
                    <Setter Property="Visibility" Value="Collapsed" />
                </Style>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="196" DisplayMemberBinding="{Binding Grouping}" />
                    <GridViewColumn Width="110" DisplayMemberBinding="{Binding Property}" />
                    <GridViewColumn Width="196" DisplayMemberBinding="{Binding Value}" />
                </GridView>
            </ListView.View>

            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock Margin="5" TextDecorations="Underline" FontSize="13" Text="{Binding Name}"/>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </ListView.GroupStyle>
        </ListView>
        <Button Name="ConfirmButton" Content="OK" Height="39" Width="160" HorizontalAlignment="Left" VerticalAlignment="Bottom"  />
        <Button Name="CancelButton" Content="Cancel" Margin="0" Width="160" Height="39" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
    </Grid>

   </Window>

推荐阅读