LoginSignup
0
0

More than 1 year has passed since last update.

Gtk3アプリのTreeViewの表示の簡略化

Last updated at Posted at 2021-04-29

Gtk3 TreeViewの表示の簡略化

gtk-Sharpチュートリアルに書かれているサンプルを簡略化します

treeViewの表示の書き方の課題

CellRendererTextやSetCellDataFuncを毎回書くのが面倒
拡張クラスの中で実行させ、書く行数を減らす

スクリーンショット 2020-03-29 12.53.22.png

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

namespace treeView3GtkApplication
{
    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.TreeViewColumnEx artistColumn = new Gtk.TreeViewColumnEx ();
            artistColumn.Title = "Artist";
            //CellRenderの生成
            artistColumn._mkCellRendererText();
            //モデルのプロパティを指定する
            artistColumn.bindingPropertyName = "Artist";

            Gtk.TreeViewColumnEx songColumn = new Gtk.TreeViewColumnEx ();
            songColumn.Title = "Song Title";
            songColumn._mkCellRendererText();
            songColumn.bindingPropertyName = "Title";

            _treeView1.AppendColumn (artistColumn);
            _treeView1.AppendColumn (songColumn);

            Gtk.ListStore musicListStore = new Gtk.ListStore (typeof (Song));
            foreach (Song song in songs) {
                musicListStore.AppendValues (song);
            }

            _treeView1._mkBinding();

            _treeView1.Model = musicListStore;
        }
    }      
    public class Song
    {
        public Song (string artist, string title)
        {
            this.Artist = artist;
            this.Title = title;
        } 
        //リフレクションを有効にするためgetとsetを書く
        public string Artist { get; set; }
        public string Title { get; set; }
    }
}

解説

リフレクションを使うため、モデルにgeter seterを書く
treeViewを拡張クラスにする
treeViewColumnにExを追加した派生クラス(継承)をにする
bindingPropertyNameにモデルのプロパティを指定する

TreeView拡張クラス
using System;
using System.Reflection;
using Gtk;

namespace Gtk{

static class GtkExtensions
{
    public static void _mkBinding(this TreeView treeView)
    {
        foreach (TreeViewColumnEx column in treeView.Columns){

            if(!(column is TreeViewColumnEx)) {
                continue;
            }
            TreeViewColumnEx columnt1 = (column as TreeViewColumnEx);
             columnt1._mkBinding();
        }
    }
}

}
TreeViewColumnEx 派生クラス
using System;
using System.Reflection;
using Gtk;
using Gdk;

public static class objectExtensions {

    public static object _performSelector_Property(this object obj, string propertyName) {

            try
            {
                Type magicType = obj.GetType();
                PropertyInfo pi = magicType.GetProperty(propertyName,
                    BindingFlags.Public | BindingFlags.NonPublic |
                    BindingFlags.Instance | BindingFlags.Static);

                MethodInfo getMethod = pi.GetGetMethod();
                object result = getMethod.Invoke(obj, null);

                return result;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
    }
}

namespace Gtk {

    public class TreeViewColumnEx : TreeViewColumn {

            public String bindingPropertyName = "";

            public CellRendererText _mkCellRendererText(string title = "",bool isPackStart = true) {

            if (title != "") {
                this.Title = title;
            }

            Gtk.CellRendererText CellRendererText1 = new Gtk.CellRendererText();
            this.PackStart(CellRendererText1, isPackStart);

            return CellRendererText1;
        }

        public CellRendererPixbuf _mkCellRendererPixbuf(string title = "",bool isPackStart = true) {
            if (title != "") {
                this.Title = title;
            }
            Gtk.CellRendererPixbuf CellRendererPixbuf1 = new Gtk.CellRendererPixbuf();
            this.PackStart(CellRendererPixbuf1, isPackStart);
            return CellRendererPixbuf1;
        }

        public CellRendererToggle _mkCellRendererToggle(string title = "",bool isPackStart = true) {
            if (title != "") {
                this.Title = title;
            }
            Gtk.CellRendererToggle CellRendererToggle1 = new Gtk.CellRendererToggle();
            this.PackStart(CellRendererToggle1, isPackStart);
            return CellRendererToggle1;
        }

        public CellRendererProgress _mkCellRendererProgress(string title = "",bool isPackStart = true) {

            if (title != "") {
                this.Title = title;
            }

            Gtk.CellRendererProgress CellRendererProgress1 = new Gtk.CellRendererProgress();
            this.PackStart(CellRendererProgress1, isPackStart);
            return CellRendererProgress1;

        }

        public void _mkBinding() {
            if(this.Cells.Length > 0) {
                this.SetCellDataFunc(this.Cells[0], new Gtk.TreeCellDataFunc(_RenderCellDo));
            }
        }

        private void _RenderCellDo(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter) {

            if(!(column is TreeViewColumnEx)) {
                return;
            }

            TreeViewColumnEx columnt1 = (column as TreeViewColumnEx);

            if(columnt1.bindingPropertyName == "" || columnt1.bindingPropertyName == null) {
                Console.WriteLine("PropertyNameがない");
                return;
            }

            object classObj = (object)model.GetValue(iter, 0);

            object value = classObj._performSelector_Property(columnt1.bindingPropertyName);

            if (value != null && cell is Gtk.CellRendererText && (value is String)) {
                (cell as Gtk.CellRendererText).Text = value as String;
            }else if (value != null && cell is Gtk.CellRendererText && (value is int)) {
                (cell as Gtk.CellRendererText).Text = ((int)value).ToString();
            }else if (value != null && cell is Gtk.CellRendererText && (value is long)) {
                (cell as Gtk.CellRendererText).Text = ((long)value).ToString();
            }else if(value != null && cell is Gtk.CellRendererText && (value is DateTime)) {
                (cell as Gtk.CellRendererText).Text = ((DateTime)value).ToString();
            } else if(value != null && cell is Gtk.CellRendererPixbuf && (value is String)) {
                (cell as Gtk.CellRendererPixbuf).Pixbuf = new Pixbuf(null, (value as String));
            } else if(value != null && cell is Gtk.CellRendererToggle && (value is String)) {
                (cell as Gtk.CellRendererToggle).Active = Convert.ToBoolean((value is String));
            } else if(value != null && cell is Gtk.CellRendererProgress && (value is String)) {
                (cell as Gtk.CellRendererProgress).Value = Convert.ToInt32((value is String));
            } else if(value != null && cell is Gtk.CellRendererPixbuf && (value is byte[])) {
                (cell as Gtk.CellRendererPixbuf).Pixbuf = new Pixbuf((byte[])value);
            } else if(value != null && cell is Gtk.CellRendererToggle && (value is Boolean)) {
                (cell as Gtk.CellRendererToggle).Active = (Boolean)value;
            } else if(value != null && cell is Gtk.CellRendererProgress && (value is int)) {
                (cell as Gtk.CellRendererProgress).Value = (int)value;
            }

        }
    }
}

Gtk3アプリのComboBoxの表示の簡略化に続く

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0