###Gtk3アプリのComboBoxの表示の簡略化
ComboBoxの表示の書き方の課題
CellRendererTextやSetCellDataFuncを毎回書くのが面倒
拡張クラスの中で実行させ、書く行数を減らす
gladeファイルにCombBoxを配置します。
using System;
using System.Collections.Generic;
using Gtk;
using UI = Gtk.Builder.ObjectAttribute;
namespace ComboBoxGtkApplication
{
class MainWindow : Window
{
[UI] private ComboBox _comboBox1 = null;
List<Song> songs;
public MainWindow() : this(new Builder("MainWindow.glade"))
{
}
private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("MainWindow"))
{
builder.Autoconnect(this);
_mkComboBox();
}
void _mkComboBox()
{
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"));
_comboBox1._mkCellRendererText("Artist");
Gtk.ListStore musicListStore = new Gtk.ListStore (typeof (Song));
foreach (Song song in songs) {
musicListStore.AppendValues (song);
}
_comboBox1._mkBinding();
_comboBox1.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を書く
ComboBoxクラスを拡張クラスにする
CellRendererTextExにCellRendererTextを親クラスにした派生クラス(継承)を作る
CellRendererTextExの中にbindingPropertyNameにモデルのプロパティを指定する
####ComboBoxクラスを拡張クラス
CellRendererTextを継承クラスにする
using System;
using System.Reflection;
using Gdk;
using Gtk;
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);
}
return null;
}
}
namespace Gtk {
public partial class CellRendererTextEx : Gtk.CellRendererText {
public string BindingPropertyName = "";
}
public static partial class ComboxExtensions {
static public void _comboInit(ComboBox Combox1)
{
Combox1.Clear();
}
static public Gtk.CellRendererText _mkCellRendererText(this ComboBox Combox1 ,string baindingName) {
_comboInit(ComboBox);
Gtk.CellRendererTextEx CellRendererTextEx1 = new Gtk.CellRendererTextEx();
CellRendererTextEx1.BindingPropertyName = baindingName;
Combox1.PackStart(CellRendererTextEx1, true);
return CellRendererTextEx1;
}
static public void _mkBinding(this ComboBox Combox1) {
if(Combox1.Cells.Length > 0) {
Combox1.SetCellDataFunc(Combox1.Cells[0], new Gtk.CellLayoutDataFunc(_RenderComboDo));
}
}
static private void _RenderComboDo(
Gtk.ICellLayout cell_layout,
Gtk.CellRenderer cell,
Gtk.ITreeModel model,
Gtk.TreeIter iter) {
if(!(cell is Gtk.CellRendererTextEx)) {
return;
}
if((cell as Gtk.CellRendererTextEx).BindingPropertyName == "" ||
(cell as Gtk.CellRendererTextEx).BindingPropertyName == null) {
Console.WriteLine("PropertyNameがない");
return;
}
object classObj = (object)model.GetValue(iter, 0);
object value = classObj._performSelector_Property((cell as Gtk.CellRendererTextEx).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.CellRendererPixbuf && (value is String)) {
(cell as Gtk.CellRendererPixbuf).Pixbuf = new Pixbuf((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;
}else if(value != null && cell is Gtk.CellRendererProgress && (value is int)) {
(cell as Gtk.CellRendererProgress).Value = (int)value;
}
}
}
}