業務のためのC#・C言語・C++学習

主にC#の文法やWPF周りのアウトプットに利用してます。

【C#-WPF】ListViewを用い表形式のデータを表示する方法

WPFにおいてListViewを用い表形式のデータを表示するには”XAMLに直接記述する方法”、"コードビハインドに記述"、"MVVMで記述"があります。 一般的には"コードビハインドに記述"か"MVVMで記述"になります。

また表形式の表示にはListViewとDataGridによる方法がありますが、この記事ではListViewを用います。

DataGridによる方法はこちらを参照してください。 gaishiengineer.hatenablog.com

作成したいUI

ボタンをクリックすると項目~項目3に値が任意の値が表示。 変数の代入はソースコード上で実現したいとします。

コードビハインドに記述

XAML

ListViewとListViewにデータを追加するボタンを配置。
ListViewの中にGridViewを入れることで行と列に値を配置できる表を作成。
GridViewColumn にデータバインディングで表示させる変数を作成。

<Window x:Class="Listview0.MainWindow"
        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:Listview0"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid Margin="0,67,-0.4,0">
        <Button Content="Button" HorizontalAlignment="Left" Margin="21,-41,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        <ListView Margin="0,0,9.6,0">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="項目" Width="200" DisplayMemberBinding="{Binding items}"/>
                    <GridViewColumn Header="項目1" Width="200" DisplayMemberBinding="{Binding items1}"/>
                    <GridViewColumn Header="項目2" Width="200" DisplayMemberBinding="{Binding items2}"/>
                    <GridViewColumn Header="項目3" Width="200" DisplayMemberBinding="{Binding items3}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>
コードビハインド

データを格納するListViewItemsクラスを作ります。
Button_Clickの中でデータを格納するリストを作りAddメソッドでデータを入れていきます。
ここではListViewItemsクラスの初期化に、オブジェクト初期化を用いています。

namespace Listview0
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            List<ListViewItems> items = new List<ListViewItems>();
            items.Add(new ListViewItems() { items = "000", items1 = "111", items2 = "222", items3 = "333" });
            items.Add(new ListViewItems() { items = "aaa", items1 = "bbb", items2 = "ccc", items3 = "ddd" });
            items.Add(new ListViewItems() { items = "AAA", items1 = "BBB", items2 = "CCC", items3 = "DDD" });
            ListViewName.ItemsSource = items;
        }
    }

    public class ListViewItems
    {
        public string items { get; set; } //XAMLで指定した変数
        public string items1 { get; set; }
        public string items2 { get; set; }
        public string items3 { get; set; }
    }
}
実行結果

実行するとListViewにデータが表示されます。 しかしUIを右端に伸ばすとListViewの列に空白ができてしまいます。 対策は調査中です。

修正版:ListViewItemsクラスの初期化に、コンストラクタを用いる場合

プログラマーの好き嫌いはあると思いますが、オブジェクト初期化ではなくコンストラクタでもOKです。

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            List<ListViewItems> items = new List<ListViewItems>();
            //items.Add(new ListViewItems() { items = "000", items1 = "111", items2 = "222", items3 = "333" });
            //items.Add(new ListViewItems() { items = "aaa", items1 = "bbb", items2 = "ccc", items3 = "ddd" });
            //items.Add(new ListViewItems() { items = "AAA", items1 = "BBB", items2 = "CCC", items3 = "DDD" });
            items.Add(new ListViewItems("000","111","222","333"));
            items.Add(new ListViewItems("aaa","bbb","ccc", "ddd"));
            items.Add(new ListViewItems("AAA","BBB","CCC", "DDD"));

            ListViewName.ItemsSource = items;
        }
    }

    public class ListViewItems
    {
        public ListViewItems(string items, string items1, string items2, string items3)
        {
            this.items = items;
            this.items1 = items1;
            this.items2 = items2;
            this.items3 = items3;
        }

        public string items { get; set; }
        public string items1 { get; set; }
        public string items2 { get; set; }
        public string items3 { get; set; }
    }

"MVVMで記述"

MVVMパターンなのでView、ViewModel、Modelの3つのソースコードに分けてUIを作っていのが普通ですが、今回は特に内部的な実行するようなものがないので、以下の通りViewとViewModelのソースコードを作ります。

View

XAML

<Window x:Class="TablebyListView_MVVM.MainWindow"
        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:TablebyListView_MVVM"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ListView ItemsSource="{Binding ListViewName, UpdateSourceTrigger=PropertyChanged}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="項目" Width="200" DisplayMemberBinding="{Binding items}"/>
                    <GridViewColumn Header="項目1" Width="200" DisplayMemberBinding="{Binding items1}"/>
                    <GridViewColumn Header="項目2" Width="200" DisplayMemberBinding="{Binding items2}"/>
                    <GridViewColumn Header="項目3" Width="200" DisplayMemberBinding="{Binding items3}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

MainWindow.xmal.cs

namespace TablebyListView_MVVM
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var context = new MainViewModel();
            this.DataContext = context;

        }
    }
}
ViewModel
namespace TablebyListView_MVVM
{
    public class MainViewModel:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public List<ListViewItems> items { get; set; }

        public MainViewModel()
        {

            items = new List<ListViewItems>();
            items.Add(new ListViewItems("000", "111", "222", "333"));
            items.Add(new ListViewItems("aaa", "bbb", "ccc", "ddd"));
            items.Add(new ListViewItems("AAA", "BBB", "CCC", "DDD"));
        } 

        public List<ListViewItems> ListViewName
        {
            get { return items; }
            set
            {
                items = value;
                RaisePropertyChanged("ListViewName");
            }
        }
    }

    public class ListViewItems: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }

        }
        public ListViewItems(string items, string items1, string items2, string items3)
        {
            this.items = items;
            this.items1 = items1;
            this.items2 = items2;
            this.items3 = items3;
        }

        public string items { get; set; }
        public string items1 { get; set; }
        public string items2 { get; set; }
        public string items3 { get; set; }
    }
}
実行結果

items~items3の値が実行途中に変更される可能性がある場合にはこれらも変更できるようRaisePropertyChanged()実装を行う。

 private string _items;
        public string items
        {
            get { return _items; }
            set
            {
                _items = value;
                RaisePropertyChanged("items");
            }
        }

        private string _items1;
        public string items1
        {
            get { return _items1; }
            set
            {
                _items1 = value;
                RaisePropertyChanged("items1");
            }
        }

        private string _items2;
        public string items2
        {
            get { return _items2; }
            set
            {
                _items2 = value;
                RaisePropertyChanged("items2");
            }
        }

        private string _items3;
        public string items3
        {
            get { return _items3; }
            set
            {
                _items3 = value;
                RaisePropertyChanged("items3");
            }
        }