0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2021-09-13

###Gtk3 TreeViewの表示の簡略化 Part3

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

####前回からの改良点
TreeView上のCell内で値を編集できるようにした

スクリーンショット 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(_treeView1 , "",100);
            //モデルのプロパティを指定する
            artistColumn.bindingPropertyName = "Artist";

            Gtk.TreeViewColumnEx songColumn = new Gtk.TreeViewColumnEx ();
            songColumn.Title = "Song Title";
            songColumn._mkCellRendererText(_treeView1 , "",100);
            songColumn.bindingPropertyName = "Title";
    
            Gtk.ListStore musicListStore = new Gtk.ListStore (typeof (Song));
            foreach (Song song in songs) {
                musicListStore.AppendValues (song);
            }
            
            _treeView1.Model = musicListStore;

            _treeView1._mkBinding();            
  
        }
    }      
    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; }
    }
}

#####TreeView拡張クラス

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);
            }
    }

    public static void _setSelector_Property(this object obj, string propertyName ,dynamic value) {
        try
            {
                Type t = obj.GetType();
                PropertyInfo pi = t.GetProperty(propertyName,
                    BindingFlags.Public  
                    | BindingFlags.NonPublic |
                    BindingFlags.Instance | BindingFlags.Static); 

                MethodInfo setMethod = pi.GetSetMethod();
                setMethod.Invoke(obj, new Object[1] { value });

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


namespace Gtk {
    public class TreeViewColumnEx : TreeViewColumn {

        public String bindingPropertyName = "";
        private Gtk.ListStore listStore1 = null;
        public CellRendererText _mkCellRendererText(TreeView treeView , string title = "" , int width = 0 , bool isEditable = true, bool isExpand = false, bool isPackStart = true) {
            if (title != "") {
                this.Title = title;
            }
            Gtk.CellRendererTextEx CellRendererText1 = new Gtk.CellRendererTextEx();
            if (width != 0) {
                this.MinWidth = width;
            }
            this.Expand = isExpand;
            this.Sizing = TreeViewColumnSizing.Autosize;
            this.PackStart(CellRendererText1, isPackStart);
            listStore1 = (ListStore)treeView.Model;
            if (isEditable)
            {
                CellRendererText1.Editable = true;
                CellRendererText1.Edited += delegate(object o, EditedArgs args)
                {
                  
                    Gtk.CellRendererTextEx o1 = (Gtk.CellRendererTextEx)o;
                    TreePath treePath1 = new TreePath (args.Path);
                    TreeIter iter;
                    if (listStore1 != null)
                    {
                        listStore1.GetIter (out iter, treePath1);
                        object testModel1 = (object)listStore1.GetValue(iter, 0);
                        _setModelData(testModel1, bindingPropertyName, args.NewText);
                    }
                };
            }

            treeView.AppendColumn(this);
            return CellRendererText1;
        }

        public CellRendererPixbuf _mkCellRendererPixbuf(TreeView treeView , string title = "" ,int width = 0 , bool isExpand = false ,bool isPackStart = true) {
         
            if (title != "") {
                this.Title = title;
            }
            Gtk.CellRendererPixbuf CellRendererPixbuf1 = new Gtk.CellRendererPixbuf();

            if (width != 0) {
                this.MinWidth = width;
            }
            this.Expand = isExpand;
            this.Sizing = TreeViewColumnSizing.Autosize;
            listStore1 = (ListStore)treeView.Model;
            this.PackStart(CellRendererPixbuf1, isPackStart);
            //this.AddAttribute (CellRendererPixbuf1, "pixbuf", 0);  
            treeView.AppendColumn(this);
            return CellRendererPixbuf1;
        }

        public CellRendererToggle _mkCellRendererToggle(TreeView treeView , string title = "",int width = 0 , bool isToggled = false ,bool isExpand = false ,bool isPackStart = true) {
            if (title != "") {
                this.Title = title;
            }
            Gtk.CellRendererToggle CellRendererToggle1 = new Gtk.CellRendererToggle();
            if (width != 0) {
                this.MinWidth = width;
            }
            this.Expand = isExpand;
            this.Sizing = TreeViewColumnSizing.Autosize;
            listStore1 = (ListStore)treeView.Model;
            if (isToggled)
            {
                CellRendererToggle1.Toggled += delegate(object o, ToggledArgs args)
                {
                    TreeIter iter;
                    if (listStore1.GetIterFromString(out iter, args.Path))
                    {
                        object object1 = (object)listStore1.GetValue(iter, 0);
                        object value = object1._performSelector_Property(bindingPropertyName);
                        String val = Convert.ToBoolean(value) == true ? "false" : "true";
                        _setModelData(object1, bindingPropertyName, val);
                    }
                };
            }

            this.PackStart(CellRendererToggle1, isPackStart);
            treeView.AppendColumn(this);
            return CellRendererToggle1;
        }

        public CellRendererProgress _mkCellRendererProgress(TreeView treeView , string title = "", int width = 0 , bool isExpand = false ,bool isPackStart = true) {
            if (title != "") {
                this.Title = title;
            }
            Gtk.CellRendererProgress CellRendererProgress1 = new Gtk.CellRendererProgress();
            if (width != 0) {
                this.MinWidth = width;
            }
            this.Expand = isExpand;
            this.Sizing = TreeViewColumnSizing.Autosize;
            listStore1 = (ListStore)treeView.Model;
            this.PackStart(CellRendererProgress1, isPackStart);
            treeView.AppendColumn(this);
            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 column1 = (column as TreeViewColumnEx);

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

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

            object value = modelData._performSelector_Property(column1.bindingPropertyName);

            _setCellData(value, cell);

        }
        private void _setCellData(object value ,Gtk.CellRenderer cell)
        {
            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;
            }
        }
        
        private void _setModelData(object modelData1 , String bindingPropertyName1 , String value )
        {

            Type t = modelData1._getKata(bindingPropertyName1);
            if (value != null && t.Equals(typeof(String))) {
                modelData1._setSelector_Property(bindingPropertyName1, Convert.ToString(value));
            }else if (value != null && t.Equals(typeof(int))) {
                modelData1._setSelector_Property(bindingPropertyName1, Convert.ToInt32(value));
            }else if (value != null && t.Equals( typeof(double))) {
                modelData1._setSelector_Property(bindingPropertyName1, Convert.ToDouble(value));
            }else if (value != null && t.Equals(typeof(long))) {
                modelData1._setSelector_Property(bindingPropertyName1, Convert.ToInt64(value));
            }else if (value != null && t.Equals( typeof(Boolean))) {
                modelData1._setSelector_Property(bindingPropertyName1,Convert.ToBoolean(value));
            }else if (value != null && t.Equals( typeof(bool))) {
                modelData1._setSelector_Property(bindingPropertyName1,Convert.ToBoolean(value));
            }else if (value != null && t.Equals( typeof(DateTime))) {
                modelData1._setSelector_Property(bindingPropertyName1, Convert.ToDateTime(value));
            }else if (value != null && t.Equals( typeof(decimal))) {
                modelData1._setSelector_Property(bindingPropertyName1, Convert.ToDecimal(value));
            }else if (value != null && t.Equals( typeof(char))) {
                modelData1._setSelector_Property(bindingPropertyName1, Convert.ToChar(value));
            }else if (value != null && t.Equals( typeof(byte))) {
                modelData1._setSelector_Property(bindingPropertyName1, Convert.ToByte(value));
            }
        }
    }
}

Gtk3アプリ RiderとT4テンプレートでHelloWorldに続く

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?