トップ回答者
WPF Listviewのヘッダー表示のカスタマイズ

質問
-
Listviewをカスタマイズし、カラムヘッダー名(GridViewColumn.header)と付加情報を上下に並べて表示したいと考えています。
サンプルソースでは、ヘッダーの中で上下にLabelを配置し、上段にカラムヘッダー名(これはスタティックなテキストです。)、下段に付加情報をContentで表示させるようにしています。
付加情報をコントロールするために、GridViewColumnを継承したクラスを作成し、GridViewColumn.headerと同じ手続きで使えるGridViewColumn.header2というプロパティーを付加しています。
Visual Basic側では、myGridView.Columns(1).header2="lower header"などとして付加情報をダイナミックに変更したいと考えています。
分からないのはXAML側の書き方です。
<DataTemplate x:Key="MyTemp0">の中でLabelを2つ配置しています。
上のLabelのContentは、Content="{Binding}"としてカラムヘッダー名をバインドしています。(この方法はあるWEBサイトから見つけましたが、なぜこれだけの記述でGridViewColumn.headerがバインドされるのか、これについても同時に御教授をお願いします。)
下のLabelではContent="header2"と固定表示になっていますが、myGridView.Columns(n).header2をバインドしてVBからContentを操作するには、どうしたら良いのでしょうか。
御回答をお願いします。
開発環境 Visual Studio 2010 Professional
VBソースコード↓
Class MainWindow
Public Class GridViewColumn_u ’ユーザー定義のGridViewColumnクラス
Inherits GridViewColumn
Public Property header2 As String
End Class
Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
Dim myGridView As New GridView()
Dim gvc0 As GridViewColumn_u
gvc0 = New GridViewColumn_u()
gvc0.Header = "Column1"
gvc0.Header2 = "2nd Line"
gvc0.Width = 100
myGridView.Columns.Add(gvc0)
myGridView.Columns(0).HeaderTemplate = CType(Me.ListView1.FindResource("MyTemp0"), System.Windows.DataTemplate)
Me.ListView1.View = myGridView
End Sub
End Class
----
XAML↓
----
<Window x:Class="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">
<StackPanel Height="305" Name="StackPanel1" Width="439" >
<ListView Height="98" Name="ListView1" Width="269" VerticalAlignment="Top"
<ListView.Resources>
<!-- Listview 個別のheaderに対するテンプレート -->
<DataTemplate x:Key="MyTemp0">
<StackPanel Orientation="Vertical" x:Name="stack0">
<Label Content="{Binding}" Background="#FFD82121" Width="70"> </Label>
<Label Content="header2" Background="#FFE89B3E" Width="70" > </Label>
</StackPanel>
</DataTemplate>
</ListView.Resources>
</ListView>
</StackPanel>
</Window>
- 編集済み 馋涎欲滴 2011年11月27日 10:12
回答
-
こんな?
<Window x:Class="MainWindow1" 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> <StackPanel Height="305" Name="StackPanel1" Width="439" > <ListView Height="98" Name="ListView1" Width="269" VerticalAlignment="Top"> <ListView.Resources> <!-- Listview 個別のheaderに対するテンプレート --> <DataTemplate x:Key="MyTemp0"> <StackPanel Orientation="Vertical" x:Name="stack0"> <Label Content="{Binding HeaderText1}" Background="#FFD82121" Width="70"></Label> <Label Content="{Binding HeaderText2}" Background="#FFE89B3E" Width="70" x:Name="HeaderLabel2" /> </StackPanel> </DataTemplate> </ListView.Resources> </ListView> </StackPanel> </Grid> </Window>
Class MainWindow1 Public Class ColumnHeaderData Implements System.ComponentModel.INotifyPropertyChanged Private _HeaderText1 As String Public Property HeaderText1() As String Get Return _HeaderText1 End Get Set(ByVal value As String) _HeaderText1 = value OnPropertyChanged("HeaderText1") End Set End Property Private _HeaderText2 As String Public Property HeaderText2() As String Get Return _HeaderText2 End Get Set(ByVal value As String) _HeaderText2 = value OnPropertyChanged("HeaderText2") End Set End Property Public Overrides Function ToString() As String Return HeaderText1 End Function Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged Protected Sub OnPropertyChanged(ByVal name As String) RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(name)) End Sub End Class Public Class GridViewColumn_u 'ユーザー定義のGridViewColumnクラス Inherits GridViewColumn Public Sub New() Me.Header = New ColumnHeaderData() End Sub Public ReadOnly Property ColumnHeaderData() As ColumnHeaderData Get Dim data As ColumnHeaderData = TryCast(Me.Header, ColumnHeaderData) If data Is Nothing Then data = New ColumnHeaderData() Me.Header = data End If Return data End Get End Property End Class Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded Dim myGridView As New GridView() headerData = New ColumnHeaderData headerData.HeaderText1 = "Column1" headerData.HeaderText2 = "2ndLine" Dim gvc0 As New GridViewColumn gvc0.Header = headerData gvc0.Width = 100 myGridView.Columns.Add(gvc0) Dim template As DataTemplate template = CType(Me.ListView1.FindResource("MyTemp0"), System.Windows.DataTemplate) Dim gvc1 As New GridViewColumn_u gvc1.Width = 100 gvc1.ColumnHeaderData.HeaderText1 = "いろはにほ" gvc1.ColumnHeaderData.HeaderText2 = Date.Now.ToString myGridView.Columns.Add(gvc1) myGridView.Columns(0).HeaderTemplate = template myGridView.Columns(1).HeaderTemplate = template Me.ListView1.View = myGridView End Sub Private headerData As ColumnHeaderData Private Sub ListView1_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles ListView1.MouseDoubleClick headerData.HeaderText1 = "あいうえお" headerData.HeaderText2 = "かきくけこ" Dim gridView As GridView = CType(Me.ListView1.View, GridView) Dim column1 As GridViewColumn_u = CType(gridView.Columns(1), GridViewColumn_u) column1.ColumnHeaderData.HeaderText1 = "ABCD" column1.ColumnHeaderData.HeaderText2 = "12345" End Sub End Class
上のLabelのContentは、Content="{Binding}"としてカラムヘッダー名をバインドしています。(この方法はあるWEBサイトから見つけましたが、なぜこれだけの記述でGridViewColumn.headerがバインドされるのか、これについても同時に御教授をお願いします。)
GridViewColumnのHeaderプロパティにセットしてあるデータが、DataTemplateで生成されたヘッダーの中身のDataContextになるからです。
そのためPathを指定してないBindingではその文字列が表示されます。
#文字列でないときはLabelで文字列になるように変換されるここで、GridViewColumnのHeaderプロパティに文字以外のデータ(上記コードではColumnHeaderDataクラス)を入れてやることで複数の内容をヘッダーの内側に伝えることができます。
GridViewColumn.headerと同じ手続きで使えるGridViewColumn.header2というプロパティーを付加しています。
XAML側でも同じ手続きにするにはDependencyPropertyにする必要があるので、ちょっと面倒になります。
継承とか考えずにHeaderプロパティに入れるデータのほうを変えたほうが楽ですよ。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)- 回答としてマーク 馋涎欲滴 2011年11月28日 13:14
すべての返信
-
こんな?
<Window x:Class="MainWindow1" 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> <StackPanel Height="305" Name="StackPanel1" Width="439" > <ListView Height="98" Name="ListView1" Width="269" VerticalAlignment="Top"> <ListView.Resources> <!-- Listview 個別のheaderに対するテンプレート --> <DataTemplate x:Key="MyTemp0"> <StackPanel Orientation="Vertical" x:Name="stack0"> <Label Content="{Binding HeaderText1}" Background="#FFD82121" Width="70"></Label> <Label Content="{Binding HeaderText2}" Background="#FFE89B3E" Width="70" x:Name="HeaderLabel2" /> </StackPanel> </DataTemplate> </ListView.Resources> </ListView> </StackPanel> </Grid> </Window>
Class MainWindow1 Public Class ColumnHeaderData Implements System.ComponentModel.INotifyPropertyChanged Private _HeaderText1 As String Public Property HeaderText1() As String Get Return _HeaderText1 End Get Set(ByVal value As String) _HeaderText1 = value OnPropertyChanged("HeaderText1") End Set End Property Private _HeaderText2 As String Public Property HeaderText2() As String Get Return _HeaderText2 End Get Set(ByVal value As String) _HeaderText2 = value OnPropertyChanged("HeaderText2") End Set End Property Public Overrides Function ToString() As String Return HeaderText1 End Function Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged Protected Sub OnPropertyChanged(ByVal name As String) RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(name)) End Sub End Class Public Class GridViewColumn_u 'ユーザー定義のGridViewColumnクラス Inherits GridViewColumn Public Sub New() Me.Header = New ColumnHeaderData() End Sub Public ReadOnly Property ColumnHeaderData() As ColumnHeaderData Get Dim data As ColumnHeaderData = TryCast(Me.Header, ColumnHeaderData) If data Is Nothing Then data = New ColumnHeaderData() Me.Header = data End If Return data End Get End Property End Class Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded Dim myGridView As New GridView() headerData = New ColumnHeaderData headerData.HeaderText1 = "Column1" headerData.HeaderText2 = "2ndLine" Dim gvc0 As New GridViewColumn gvc0.Header = headerData gvc0.Width = 100 myGridView.Columns.Add(gvc0) Dim template As DataTemplate template = CType(Me.ListView1.FindResource("MyTemp0"), System.Windows.DataTemplate) Dim gvc1 As New GridViewColumn_u gvc1.Width = 100 gvc1.ColumnHeaderData.HeaderText1 = "いろはにほ" gvc1.ColumnHeaderData.HeaderText2 = Date.Now.ToString myGridView.Columns.Add(gvc1) myGridView.Columns(0).HeaderTemplate = template myGridView.Columns(1).HeaderTemplate = template Me.ListView1.View = myGridView End Sub Private headerData As ColumnHeaderData Private Sub ListView1_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles ListView1.MouseDoubleClick headerData.HeaderText1 = "あいうえお" headerData.HeaderText2 = "かきくけこ" Dim gridView As GridView = CType(Me.ListView1.View, GridView) Dim column1 As GridViewColumn_u = CType(gridView.Columns(1), GridViewColumn_u) column1.ColumnHeaderData.HeaderText1 = "ABCD" column1.ColumnHeaderData.HeaderText2 = "12345" End Sub End Class
上のLabelのContentは、Content="{Binding}"としてカラムヘッダー名をバインドしています。(この方法はあるWEBサイトから見つけましたが、なぜこれだけの記述でGridViewColumn.headerがバインドされるのか、これについても同時に御教授をお願いします。)
GridViewColumnのHeaderプロパティにセットしてあるデータが、DataTemplateで生成されたヘッダーの中身のDataContextになるからです。
そのためPathを指定してないBindingではその文字列が表示されます。
#文字列でないときはLabelで文字列になるように変換されるここで、GridViewColumnのHeaderプロパティに文字以外のデータ(上記コードではColumnHeaderDataクラス)を入れてやることで複数の内容をヘッダーの内側に伝えることができます。
GridViewColumn.headerと同じ手続きで使えるGridViewColumn.header2というプロパティーを付加しています。
XAML側でも同じ手続きにするにはDependencyPropertyにする必要があるので、ちょっと面倒になります。
継承とか考えずにHeaderプロパティに入れるデータのほうを変えたほうが楽ですよ。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)- 回答としてマーク 馋涎欲滴 2011年11月28日 13:14