VB のたまご

作成日: 2017/03/05, 更新日: 2017/03/05



ListView

    イメージ
  •  ListView は、表形式のデータを表すコントロールです。 WinForms の ListView は、大きいアイコン、小さいアイコン、詳細、等いくつかの表示モードを選択することができましたが、 WPF の ListView は詳細のみとなります。

  •  とりあえずどういう風に動くのか見てみましょう。 以下サンプルです。「ListViewWindow1」という画面で作成していますが、「MainWindow」に書いても構いません。

  • スポンサーリンク


    <Window x:Class="ListViewWindow1"
            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:z04_NormalControls"
            mc:Ignorable="d"
            Title="ListViewWindow1" Height="300" Width="300">
    
        <StackPanel>
    
            <StackPanel Margin="10">
                <Button Name="button1" Content="データ追加" Click="Click" />
                <ListView Name="listview1">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Header="名前" DisplayMemberBinding="{Binding Name}" Width="100" />
                            <GridViewColumn Header="年齢" DisplayMemberBinding="{Binding Age}" Width="50" />
                            <GridViewColumn Header="男性?" DisplayMemberBinding="{Binding IsMan}" Width="50" />
                        </GridView>
                    </ListView.View>
                </ListView>
    
            </StackPanel>
            
        </StackPanel>
    
    </Window>
    

    Public Class ListViewWindow1
    
        Private Sub Click(sender As Object, e As RoutedEventArgs)
    
            Dim items = New List(Of Person)(Enumerable.Range(1, 100).Select(Function(i) New Person With {
                                                                             .Name = "taro" + i.ToString(),
                                                                             .Age = 20 + i,
                                                                             .IsMan = i Mod 3 = 0}))
    
            Me.listview1.ItemsSource = items
    
        End Sub
    
        Private Class Person
    
            Public Property Name As String = String.Empty
            Public Property Age As Integer = -1
            Public Property IsMan As Boolean = False
    
        End Class
    
    End Class
    

  •  DataGrid と似たような見た目をしています。ところでデータが見切れてしまいます。これは親コントロールに StackPanel を敷いているためで、全データを表示できる分の長さまで伸びてしまうためです。 これを回避するため、以下のように修正します。※これ以外にも対処方法はあると思いますが、一例ということで。

  • <Window x:Class="ListViewWindow2"
            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:z04_NormalControls"
            mc:Ignorable="d"
            Title="ListViewWindow2" Height="300" Width="300">
    
        <Grid>
    
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
    
            <Button Name="button1" Content="データ追加" Click="Click" />
    
            <ListView Name="listview1" Grid.Row="1">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="名前" DisplayMemberBinding="{Binding Name}" Width="100" />
                        <GridViewColumn Header="年齢" DisplayMemberBinding="{Binding Age}" Width="50" />
                        <GridViewColumn Header="男性?" DisplayMemberBinding="{Binding IsMan}" Width="50" />
                    </GridView>
                </ListView.View>
            </ListView>
    
        </Grid>
    
    </Window>
    

    Public Class ListViewWindow2
    
        Private Sub Click(sender As Object, e As RoutedEventArgs)
    
            Dim items = New List(Of Person)(Enumerable.Range(1, 100).Select(Function(i) New Person With {
                                                                             .Name = "taro" + i.ToString(),
                                                                             .Age = 20 + i,
                                                                             .IsMan = i Mod 3 = 0}))
    
            Me.listview1.ItemsSource = items
    
        End Sub
    
        Private Class Person
    
            Public Property Name As String = String.Empty
            Public Property Age As Integer = -1
            Public Property IsMan As Boolean = False
    
        End Class
    
    End Class
    

  •  親コントロールを Grid に変更しています。コードビハインドは修正は無しでそのままです。 これで実行するとスクロール領域が表示されて最後までデータを見ることができるようになりました。

  • スポンサーリンク


  •  続いて、行選択した時のイベント処理です。

  • <Window x:Class="ListViewWindow3"
            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:z04_NormalControls"
            mc:Ignorable="d"
            Title="ListViewWindow3" Height="300" Width="300">
    
        <Grid>
    
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
    
            <Button Name="button1" Content="データ追加" Click="Click" />
    
            <ListView Name="listview1" Grid.Row="1" SelectionChanged="SelectionChanged">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="名前" DisplayMemberBinding="{Binding Name}" Width="100" />
                        <GridViewColumn Header="年齢" DisplayMemberBinding="{Binding Age}" Width="50" />
                        <GridViewColumn Header="男性?" DisplayMemberBinding="{Binding IsMan}" Width="50" />
                    </GridView>
                </ListView.View>
            </ListView>
    
        </Grid>
    
    </Window>
    

    Public Class ListViewWindow3
    
        Private Sub Click(sender As Object, e As RoutedEventArgs)
    
            Dim items = New List(Of Person)(Enumerable.Range(1, 100).Select(Function(i) New Person With {
                                                                             .Name = "taro" + i.ToString(),
                                                                             .Age = 20 + i,
                                                                             .IsMan = i Mod 3 = 0}))
    
            Me.listview1.ItemsSource = items
    
        End Sub
    
        Private Class Person
    
            Public Property Name As String = String.Empty
            Public Property Age As Integer = -1
            Public Property IsMan As Boolean = False
    
        End Class
    
        Private Sub SelectionChanged(sender As Object, e As SelectionChangedEventArgs)
    
            ' Remove は、変更前の選択項目
            If 0 < e.RemovedItems.Count Then
                Console.WriteLine($"")
                For Each item As Person In e.RemovedItems
                    Console.WriteLine($"{item.Name} remove.")
                Next
            End If
    
            ' Add は、変更後の選択項目
            If 0 < e.AddedItems.Count Then
                For Each item As Person In e.AddedItems
                    Console.WriteLine($"{item.Name} add.")
                Next
            End If
    
        End Sub
    
    End Class
    

  •  SelectionChanged イベントの引数からは、変更前と変更後の値を取得することができます。これを使って、変更した値を調べています。 イベント引数名には、RemovedItems, AddedItems とありますが、ここの例では、「選択項目の削除」や「新規項目の追加」という意味ではありません。