Gtk3アプリのTreeViewの表示

### Gtk3のTreeViewの表示

<a href="https://www.mono-project.com/docs/gui/gtksharp/widgets/treeview-tutorial/">gtk-sharpチュートリアル</a>に書かれているサンプルをコピペするだけでTreeViewを表示できます

<img width="300" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/80c46f90-e810-ce50-5fda-0a382a202f90.png">

[gtk-sharp TreeView Tutorial](https://www.mono-project.com/docs/gui/gtksharp/widgets/treeview-tutorial/)

#### Gladeの編集
<img width="400" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/d171345b-6c48-37ef-4683-d39bb4efc6f3.png">
GladeにtreeViewを追加をします
不要なコントロールは削除しました

##### TreeViewにIdのところに名前をつけます
<img width="500" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/b48a784d-942f-30c7-4bda-2627f710e583.png">
##### TreeViewの変数を定義します。
<img width="500" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/c5996902-9d25-4bd7-27fb-bbd68f7fde6d.png">
gtk-sharpテンプレートにあった余分なイベントハンドラーは削除しました。

```cs
using System;
using Gtk;
using UI = Gtk.Builder.ObjectAttribute;

namespace treeViewGtkApplication
{
    class MainWindow : Window
    {
        [UI] private TreeView _treeView1 = null;

        public MainWindow() : this(new Builder("MainWindow.glade"))
        {
        }

        private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("MainWindow"))
        {
            builder.Autoconnect(this);
            _mkTreeView();
        }

         void _mkTreeView()
        {
            Gtk.TreeViewColumn artistColumn = new Gtk.TreeViewColumn ();
            artistColumn.Title = "Artist";
 
            // アーティスト名を表示するテキストセルを作成する
            Gtk.CellRendererText artistNameCell = new Gtk.CellRendererText ();
 
            // セルを列に追加する
            artistColumn.PackStart (artistNameCell, true);
 
            // 曲名の列を作る
            Gtk.TreeViewColumn songColumn = new Gtk.TreeViewColumn ();
            songColumn.Title = "曲名";
 
            // 曲名の列にも同じことをする
            Gtk.CellRendererText songTitleCell = new Gtk.CellRendererText ();
            songColumn.PackStart (songTitleCell, true);
 
            // TreeViewにカラムを追加する
            _treeView1.AppendColumn (artistColumn);
            _treeView1.AppendColumn (songColumn);
 
            // モデル内のどのアイテムを表示するかをセルレンダラーに伝える
            artistColumn.AddAttribute (artistNameCell, "text", 0);
            songColumn.AddAttribute (songTitleCell, "text", 1);
 
            // アーティスト名と曲名の2つの文字列を保持するモデルを作成します。
            Gtk.ListStore musicListStore = new Gtk.ListStore (typeof (string), typeof (string));
 
            // ストアにデータを追加します。
            musicListStore.AppendValues ("Garbage", "Dog New Tricks");
    
            // TreeViewにモデルを割り当てる
            _treeView1.Model = musicListStore;
        }
    }
}
```

```
チュートリアルのサンプルの書き換える必要があります。
Mono
Gtk.TreeModel
↓
GTK3
Gtk.ITreeModel
```

#### Modelを使った表示の仕方

<img width="500" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/c35f90cf-d61c-9924-d42a-c47368c1b30d.png">

<a href="https://www.mono-project.com/docs/gui/gtksharp/widgets/treeview-tutorial/">チュートリアル</a>に書かれている内容をコピペで表示できました。

```cs
using System;
using System.Collections.Generic;
using Gtk;
using UI = Gtk.Builder.ObjectAttribute;

namespace treeView2Application
{
    class MainWindow : Window
    {

        [UI] private TreeView _treeView1 = null;
        
        List<Song> songs;
        
        public MainWindow() : this(new Builder("MainWindow.glade"))
        {
        }
        private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("MainWindow"))
        {
            builder.Autoconnect(this);
            _mkTreeView();
        }        
        void _mkTreeView()
        {
            songs = new List<Song>();
 
            songs.Add (new Song ("Dancing DJs vs. Roxette", "Fading Like a Flower"));
            songs.Add (new Song ("Xaiver", "Give me the night"));
            songs.Add (new Song ("Daft Punk", "Technologic"));
 
            Gtk.TreeViewColumn artistColumn = new Gtk.TreeViewColumn ();
            artistColumn.Title = "Artist";
            Gtk.CellRendererText artistNameCell = new Gtk.CellRendererText ();
            artistColumn.PackStart (artistNameCell, true);
 
            Gtk.TreeViewColumn songColumn = new Gtk.TreeViewColumn ();
            songColumn.Title = "Song Title";
            Gtk.CellRendererText songTitleCell = new Gtk.CellRendererText ();
            songColumn.PackStart (songTitleCell, true);
            
            _treeView1.AppendColumn (artistColumn);
            _treeView1.AppendColumn (songColumn);
 
            Gtk.ListStore musicListStore = new Gtk.ListStore (typeof (Song));
            foreach (Song song in songs) {
                musicListStore.AppendValues (song);
            }
 
            artistColumn.SetCellDataFunc (artistNameCell, new Gtk.TreeCellDataFunc (RenderArtistName));
            songColumn.SetCellDataFunc (songTitleCell, new Gtk.TreeCellDataFunc (RenderSongTitle));
 
            _treeView1.Model = musicListStore;

        }        
        private void RenderArtistName (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter)
        {
            Song song = (Song) model.GetValue (iter, 0);
 
            if (song.Artist.StartsWith ("X") == true) {
                (cell as Gtk.CellRendererText).Foreground = "red";
            } else {
                (cell as Gtk.CellRendererText).Foreground = "darkgreen";
            }
 
            (cell as Gtk.CellRendererText).Text = song.Artist;
        } 
        private void RenderSongTitle (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter)
        {
            Song song = (Song) model.GetValue (iter, 0);
            (cell as Gtk.CellRendererText).Text = song.Title;
        }
    }      
    public class Song
    {
        public Song (string artist, string title)
        {
            this.Artist = artist;
            this.Title = title;
        } 
        public string Artist;
        public string Title;
    }
}
```

#### 課題
レンダー用の関数を毎回書かないといけなく面倒
SetCellDataFunc関数を毎回書かないようにしたい。

### 追記
http://blog.borovsak.si/2009/09/glade3-tutorial-2-constructing.html

[Gtk3アプリ TreeViewプログラム自動生成ツール](https://qiita.com/iota_11/items/7074e21bf99cc56b69ce)

<a href="https://qiita.com/tana_/items/c3c7ffeb8f922d69d004">Gtk3アプリのTreeViewの表示の簡略化</a>に続く