極力 Blendを使って ListView を使ったシンプルなアプリを作ってみます。
こんな画面のプログラムを作ります。
(1) まずはWPFのプロジェクトを新規作成します。
(2) ListViewコントロールを全面にして貼り付けます。
(3) サンプルデータを作ります。ここでは Name と Address の2つの文字列データをサンプルデータとして作成します。
4) このサンプルデータを Grid の DataContext にバインドします。
ここでは”StaticResource”から”SampleDataSource”を選択します。
(5) 次に ListView の ItemsSource へ 先に設定した SampleDataSource の Collection を設定します。
(6) 続けて、ListView の GridViewColumn の設定を行います。
ここでは、”Name” と ”Address” の2つの列を作成してみます。
各 DisplayMemberBinding は ”データコンテキスト” の対応するアイテムを選択します。
以上で完成です。
(7) 動かしてみよう
[F5]でプログラムを動かしてみます。こんな感じです。
この時点の XAML は以下の通り。動いてしまえば簡単ですね。
[MainWindow.xaml]<Window x:Class="ListViewSimple_2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid DataContext="{Binding Mode=OneWay, Source={StaticResource SampleDataSource}}"> <ListView ItemsSource="{Binding Collection}"> <ListView.View> <GridView> <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/> <GridViewColumn Header="Address" DisplayMemberBinding="{Binding Address}"/> </GridView> </ListView.View> </ListView> </Grid> </Window>
先ほど作ったプログラムの実行画面を見てみましょう。ヘッダ部分だけ中央に寄っています。
ヘッダの部分も左寄せにしてみたいですね。というわけで、ヘッダ部分も文字を左寄せにしてみます。
実は、少々面倒です。Blendでは設定できませんでした。XAMLの直接修正で実現します。
[MainWindow.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" mc:Ignorable="d" x:Class="ListViewSimple.MainWindow" Title="MainWindow" Height="350" Width="525"> <Grid DataContext="{Binding Mode=oneway, Source={StaticResource SampleDataSource}}"> <ListView ItemsSource="{Binding Collection}"> <ListView.View> <GridView> <!-- <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/> --> <GridViewColumn DisplayMemberBinding="{Binding Name}"> <GridViewColumn.Header> <GridViewColumnHeader Content="Name" HorizontalContentAlignment="Left"/> </GridViewColumn.Header> </GridViewColumn> <!-- <GridViewColumn Header="Address" DisplayMemberBinding="{Binding Address}"/> --> <GridViewColumn DisplayMemberBinding="{Binding Address}"> <GridViewColumn.Header> <GridViewColumnHeader Content="Address" HorizontalContentAlignment="Left"/> </GridViewColumn.Header> </GridViewColumn> </GridView> </ListView.View> </ListView> </Grid> </Window>
修正したXAMLでコンパイルしたプログラムの実行結果は下記の通りです。
ちゃんと左寄せ(Left)になりました。同様に Right
を設定すれば右寄せにもできます。
1行目にイメージを表示するように変更します。
まず最初にすることは画像データをSampleDataに加えることです。
Images という名称で下記のようにサンプルに加えました。
作成したプログラムは下記の通り。
作成したXAMLは下記の通り。
StackPanel は無くても良いのですが、後述の説明の都合で入れてあります。
<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" mc:Ignorable="d" x:Class="ListViewSimple.MainWindow" Title="MainWindow" Height="350" Width="525"> <Grid DataContext="{Binding Mode=oneway, Source={StaticResource SampleDataSource}}"> <ListView ItemsSource="{Binding Collection}"> <ListView.View> <GridView> <GridViewColumn Header="Images"> <GridViewColumn.CellTemplate> <DataTemplate> <StackPanel> <Image Source="{Binding Path=Images}" Width="64"></Image> </StackPanel> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/> <GridViewColumn Header="Address" DisplayMemberBinding="{Binding Address}"/> </GridView> </ListView.View> </ListView> </Grid> </Window>
1行目に表示していたイメージと、2行目に表示していた名前、の2つを1つのセルに融合して表示します。
[MainWindow.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" mc:Ignorable="d" x:Class="ListViewSimple.MainWindow" Title="MainWindow" Height="350" Width="525"> <Grid DataContext="{Binding Mode=oneway, Source={StaticResource SampleDataSource}}"> <ListView ItemsSource="{Binding Collection}"> <ListView.View> <GridView> <GridViewColumn Header="Name"> <GridViewColumn.CellTemplate> <DataTemplate> <StackPanel> <Image Source="{Binding Path=Images}" Width="64"></Image> <TextBlock Text="{Binding Path=Name}"/> </StackPanel> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="Address" DisplayMemberBinding="{Binding Address}"/> </GridView> </ListView.View> </ListView> </Grid> </Window>
だんだん難しくなってきます。
ここでは、
ListView を使って下図のようなタイル表示を行う方法を記載します。
「Pro WPF 4.5 in C#」の本で、Chapter 22 にて"Creating a Custum View"として紹介されている内容です。
ほとんど本に記載のままですが、若干独自の処理を加えています。
(1) まず、次の2つのソースファイル(TileView.cs、Generic.xaml)をプロジェクトへ追加します。
[TileView.cs]using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace ListViewStyle { public class TileView : ViewBase { private DataTemplate itemTemplate; public DataTemplate ItemTemplate { get { return itemTemplate; } set { itemTemplate = value; } } private Brush selectedBackground = Brushes.Transparent; public Brush SelectedBackground { get { return selectedBackground; } set { selectedBackground = value; } } private Brush selectedBorderBrush = Brushes.Black; public Brush SelectedBorderBrush { get { return selectedBorderBrush; } set { selectedBorderBrush = value; } } private int selectedBorderThickness = 1; public int SelectedBorderThickness { get { return selectedBorderThickness; } set { selectedBorderThickness = value; } } private int selectedCornerRadius = 3; public int SelectedCornerRadius { get { return selectedCornerRadius; } set { selectedCornerRadius = value; } } protected override object DefaultStyleKey { get { return new ComponentResourceKey(GetType(), "TileView"); } } protected override object ItemContainerDefaultStyleKey { get { return new ComponentResourceKey(GetType(), "TileViewItem"); } } } }
[Themes / Generic.xaml]
[重要1] ”Generic.xaml” のファイルは必ず”Themes”フォルダの下に保存してください。詳細は不明。
[重要2] ”Generic.xaml” の "ビルドアクション" を
"Page" にすること。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ListViewStyle"> <Style x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:TileView}, ResourceId=TileView}" TargetType="{x:Type ListView}" BasedOn="{StaticResource {x:Type ListBox}}"> <Setter Property="BorderBrush" Value="Black"></Setter> <Setter Property="BorderThickness" Value="0.5"></Setter> <Setter Property="Grid.IsSharedSizeScope" Value="True"></Setter> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <WrapPanel Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" ></WrapPanel> </ItemsPanelTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:TileView}, ResourceId=TileViewItem}" TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}"> <Setter Property="Padding" Value="3"/> <Setter Property="HorizontalContentAlignment" Value="Center"></Setter> <Setter Property="ContentTemplate" Value="{Binding Path=View.ItemTemplate, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}}"></Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <!-- 値を直接指定する場合はこんな感じで <Border Name="Border" BorderThickness="1" CornerRadius="3" > --> <Border Name="Border" BorderThickness="{Binding Path=View.SelectedBorderThickness, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}}" CornerRadius="{Binding Path=View.SelectedCornerRadius, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}}"> <ContentPresenter /> </Border> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter TargetName="Border" Property="BorderBrush" Value="{Binding Path=View.SelectedBorderBrush, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}}"></Setter> <Setter TargetName="Border" Property="Background" Value="{Binding Path=View.SelectedBackground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}}"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
図: "Generic.xaml" のビルドアクション
(2) 次に MainWindow.xaml を以下のように修正します。
[MainWindow.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" mc:Ignorable="d" x:Class="ListViewSimple.MainWindow" xmlns:local="clr-namespace:ListViewStyle" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <local:TileView x:Key="ImageView" SelectedBackground="LightSteelBlue" SelectedBorderBrush="BlueViolet" SelectedBorderThickness="5" SelectedCornerRadius="10"> <local:TileView.ItemTemplate> <DataTemplate> <StackPanel Width="128" VerticalAlignment="Top"> <Image Source="{Binding Path=Images}"></Image> <TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" Text="{Binding Path=Name}" ></TextBlock> </StackPanel> </DataTemplate> </local:TileView.ItemTemplate> </local:TileView> <local:TileView x:Key="ImageDetailView" SelectedBackground="LightSteelBlue"> <local:TileView.ItemTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="Auto" SharedSizeGroup="Col2"></ColumnDefinition> </Grid.ColumnDefinitions> <Image Margin="5" Grid.Column="0" Width="100" Source="{Binding Path=Images}"></Image> <StackPanel Grid.Column="1" VerticalAlignment="Center"> <TextBlock FontWeight="Bold" Text="{Binding Path=Name}"></TextBlock> <TextBlock Text="{Binding Path=Address}"></TextBlock> </StackPanel> </Grid> </DataTemplate> </local:TileView.ItemTemplate> </local:TileView> <GridView x:Key="GridView"> <GridView.Columns> <GridViewColumn Header="Name"> <GridViewColumn.CellTemplate> <DataTemplate> <StackPanel> <Image Source="{Binding Path=Images}" Width="64"></Image> <TextBlock Text="{Binding Path=Name}"/> </StackPanel> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="Address" DisplayMemberBinding="{Binding Address}"/> </GridView.Columns> </GridView> </Window.Resources> <Grid DataContext="{Binding Mode=oneway, Source={StaticResource SampleDataSource}}"> <ListView View="{StaticResource ImageView}" ItemsSource="{Binding Collection}" BorderBrush="Black" BorderThickness="0.5" Foreground="Black"/> </Grid> </Window>
このまま実行すると、下図のようになります。
「View="{StaticResource ImageView}"」 を「View="{StaticResource ImageDetailView}"」へ変えると、下図の通り。
「View="{StaticResource ImageView}"」 を「View="{StaticResource GridView}"」へ変えると、下図の通り。
これらをベースにして微修正していけば、多くのバリエーションに対応できそうです。
アイテム選択時のセルの色や枠の太さ、角、色、などのカスタマイズは、上記ソース中の水色部分を参考に修正を行ってください。
”GridView” のスタイルをカスタマイズしたい場合は、下記のような感じでスタイル指定にて。
[MainWindow.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" mc:Ignorable="d" x:Class="ListViewSimple_2.MainWindow" xmlns:local="clr-namespace:ListViewSimple_2" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <local:TileView x:Key="ImageView" SelectedBorderBrush="BlueViolet" SelectedBorderThickness="5" SelectedCornerRadius="10"> <local:TileView.SelectedBackground> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FF1B6576" Offset="1"/> <GradientStop Color="White"/> <GradientStop Color="#FF9FD2DE" Offset="0.237"/> </LinearGradientBrush> </local:TileView.SelectedBackground> <local:TileView.ItemTemplate> <DataTemplate> <StackPanel Width="128" VerticalAlignment="Top"> <Image Source="{Binding Path=Images}"></Image> <TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" Text="{Binding Path=Name}" ></TextBlock> </StackPanel> </DataTemplate> </local:TileView.ItemTemplate> </local:TileView> <local:TileView x:Key="ImageDetailView" SelectedBackground="LightSteelBlue"> <local:TileView.ItemTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="Auto" SharedSizeGroup="Col2"></ColumnDefinition> </Grid.ColumnDefinitions> <Image Margin="5" Grid.Column="0" Width="100" Source="{Binding Path=Images}"></Image> <StackPanel Grid.Column="1" VerticalAlignment="Center"> <TextBlock FontWeight="Bold" Text="{Binding Path=Name}"></TextBlock> <TextBlock Text="{Binding Path=Address}"></TextBlock> </StackPanel> </Grid> </DataTemplate> </local:TileView.ItemTemplate> </local:TileView> <GridView x:Key="GridView"> <GridView.Columns> <GridViewColumn Header="Name"> <GridViewColumn.CellTemplate> <DataTemplate> <StackPanel> <Image Source="{Binding Path=Images}" Width="64"></Image> <TextBlock Text="{Binding Path=Name}" TextWrapping="Wrap"/> </StackPanel> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="Address"> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Path=Address}" TextWrapping="Wrap"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView.Columns> </GridView> <Style x:Key="MyStyle" TargetType="ListViewItem"> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="Bisque"/> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Grid DataContext="{Binding Mode=oneway, Source={StaticResource SampleDataSource}}"> <ListView ItemContainerStyle="{StaticResource MyStyle}" ItemsSource="{Binding Collection}" View="{StaticResource GridView}" BorderBrush="Black" BorderThickness="0.5" Foreground="Black" Background="White"/> </Grid> </Window>
選択時のセルの色を変えられました。
本ページの情報は、特記無い限り下記 MIT ライセンスで提供されます。
2023-05-31 | - | ページデザイン更新 |
2018-09-08 | - | "Generic.xaml" のビルドアクションに関する記述を追記 |
2014-09-08 | - | 新規作成 |