--> -->
#blog2navi() *ListViewにclassのデータを表示させる [#y8d40d95] C#でListViewを使って、フォーマットされた表示を行おうとするのですが、どうにも思うように行きません。~ 単純なExcelのような表は簡単にできても、ヤフオクの一覧のようなフォーマットされた情報が列挙される表示は、色々こねくり回す必要があるようです。~ ~ 一番参考になったのはこちらのサイト。 ~ [[How to Create a Custom View Mode for a ListView:http://msdn.microsoft.com/en-us/library/ms748859.aspx]]~ ~ 普通にMSDNですが、そこに添付されていたサンプルがまさにやりたいことでした。~ ページの内容を読み、画面下部のリンクからサンプルをダウンロードします。~ #ref(e1.png);~ ~ サンプルのままでは、各データの境界に線が無いので、以下のページを参考にTemplateをカスタマイズします。~ [[ListViewのGridViewに罫線を引きたい:http://blogs.wankuma.com/kazuki/archive/2009/05/06/172495.aspx]]~ ~ そうすると、こんな感じに表示することができます。~ #ref(e2.png);~ ~ それではソースを見ていきましょう。~ ~ MainWindow.xaml #code(HTML){{ <Window x:Class="ListViewCustomView.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Custom View" Width="400" Height="200" > <Window.Resources> <DataTemplate x:Key="checkbox"> <CheckBox IsChecked="{Binding IsSelected,RelativeSource={RelativeSource AncestorType=ListViewItem} }" Margin="0,1,1,1" /> </DataTemplate> <DataTemplate x:Key="DisplayImage"> <StackPanel Width="50"> <Image Source="{Binding Image}"/> </StackPanel> </DataTemplate> <DataTemplate x:Key="ColLabel"> <TextBlock> <Label Content="Device Name"/> <LineBreak /> <Label Content="Interval"/> <LineBreak /> <Label Content="Batery Level"/> </TextBlock> </DataTemplate> <DataTemplate x:Key="ColData"> <TextBlock> <Label Content="{Binding DeviceName}"/> <LineBreak /> <Label Content="{Binding Interval}"/> <LineBreak /> <Label Content="{Binding BatteryLevel}"/> </TextBlock> </DataTemplate> <GridView x:Key="gridView"> <GridViewColumn CellTemplate="{StaticResource checkbox}"/> <GridViewColumn Header="Image" CellTemplate="{StaticResource DisplayImage}"/> <GridViewColumn Header="ColLabel" CellTemplate="{StaticResource ColLabel}"/> <GridViewColumn Header="ColData" CellTemplate="{StaticResource ColData}"/> </GridView> <Style x:Key="lineGridStyle" TargetType="{x:Type ListViewItem}"> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListViewItem}"> <!-- まず、元の見た目を再現 --> <Grid Name="background"> <ContentControl Name="foreground"> <!-- バインドするために名前をつけた --> <GridViewRowPresenter Name="rowPresenter"/> </ContentControl> <!-- GridViewRowPresenterのColumnsとバインド! --> <ItemsControl ItemsSource="{Binding ElementName=rowPresenter, Path=Columns}"> <!-- 表示は水平方向に --> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <!-- ボーダーを表示する --> <ItemsControl.ItemTemplate> <DataTemplate> <!-- 右側と下側に罫線を引く、ボーダーの幅は列の表示幅にバインドする --> <Border Margin="1,0,0,0" BorderBrush="Gray" BorderThickness="0,0,0,1" Width="{Binding ActualWidth}"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <StackPanel> <ListView Name="lv" ItemsSource="{Binding}" FontSize="12" View="{Binding gridView}" ItemContainerStyle="{StaticResource lineGridStyle}" /> </StackPanel> </Window> }} <Window.Resources>の<DataTemplate>で各要素を定義し、<GridView>で表示フォーマットを定義しています。~ <Style>以降は境界線を引くためのものです。詳細は上記リンク先を参照してください。~ ~ 実際のデータ表示本体は、 #code(HTML){{ <StackPanel> <ListView Name="lv" ItemsSource="{Binding}" FontSize="12" View="{Binding gridView}" ItemContainerStyle="{StaticResource lineGridStyle}" /> </StackPanel> }} だけです。~ ItemsSource="{Binding}"とすることで、暗黙的にDataContextのデータがバインドされます。~ ~ 次にソース。~ MainWindow.xaml.cs #code(java){{ using System.Windows; using System.Windows.Controls; using System.Collections.Generic; namespace ListViewCustomView { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); ChangeView("GridView"); List<DispInformation> dispInformations = new List<DispInformation>(); dispInformations.Add(makeInformationsSub("ibmpc001", 5, 0.76f, "images\\fish.png")); dispInformations.Add(makeInformationsSub("toshiba", 30, 0.41f, "images\\dog.png")); dispInformations.Add(makeInformationsSub("iPhone", 15, 0.23f, "images\\flower.jpg")); this.DataContext = dispInformations; } void ChangeView(string str) { if (str == "GridView") { lv.View = lv.FindResource("gridView") as ViewBase; } } private DispInformation makeInformationsSub(string dn, int iv, float ll, string im) { DispInformation di = new DispInformation(); di.DeviceName = dn; di.Interval = iv; di.BatteryLevel = ll; di.Image = im; return di; } public class DispInformation { private string devicename; public string DeviceName { get { return devicename; } set { devicename = value; } } private int interval; public int Interval { get { return interval; } set { interval = value; } } private float batterylevel; public float BatteryLevel { get { return batterylevel; } set { batterylevel = value; } } private string image; public string Image { get { return image; } set { image = value; } } } } } }} サンプルにはこれ以外にも色々入っていますが、Viewの切り替えをしなければ画像ファイルを除いて全て不要です。~ 本当はChangeView()も不要だと思うのですが、うまく取れませんでした。~ ~ 要は、データを格納したいclassをListに詰め込んで、To.Array()でDataContextに入れてあげれば良いようです。~ 要は、データを格納したいclassをListに詰め込んでDataContextに入れてあげれば良いようです。~ ミソは以下の部分で、こういう形に書いてあげないとListViewに反映されませんでした。~ #code(java){{ : private string devicename; public string DeviceName { get { return devicename; } set { devicename = value; } } : }} ~ ここまでたどり着くのにやっぱり2日ぐらいかかったので、メモ。 ---- #htmlinsert(20130824_bind.html) ---- RIGHT:Category: [[[CSharp>日記/Category/CSharp]]] - 09:47:35 ~ RIGHT:&blog2trackback(); #comment(above) #blog2navi()