[Gtk-sharp-list] DataGrid control, data binding, ObjectViews, Swf,
Gtk
Daniel Morgan
monodanmorg at yahoo.com
Sat Nov 19 11:47:40 EST 2005
Skipped content of type multipart/alternative-------------- next part --------------
// DataGrid.cs
namespace Mono.Data.GtkSharp
{
// notice System.Data is not references here
using System;
using System.Collections;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using GLib;
using Gtk;
public class DataGridColumn
{
private string columnName = "";
private TreeViewColumn treeViewColumn = null;
public CellRendererText Renderer = null; // should be internal
public string ColumnName {
get {
return columnName;
}
set {
columnName = value;
}
}
public TreeViewColumn TreeViewColumn {
get {
return treeViewColumn;
}
set {
treeViewColumn = value;
}
}
}
public class DataGrid : VBox {
private ListStore store;
private TreeView treeView;
public ArrayList gridColumns; // TODO: make Columns a collection
public DataGrid () : base(false, 4) {
ScrolledWindow sw = new ScrolledWindow ();
this.PackStart (sw, true, true, 0);
treeView = new TreeView (store);
treeView.HeadersVisible = true;
//treeView.ModifyFont (Pango.FontDescription.FromString ("courier new"));
gridColumns = new ArrayList(0);
sw.Add (treeView);
store = new ListStore (GLib.GType.String);
treeView.EnableSearch = true;
treeView.HeadersClickable = true;
dataMember = "";
dataSource = null;
}
ArrayList bindrows = null;
object resolvedDataSource = null;
private bool editable = true;
private object dataSource;
private string dataMember;
public int SelectedRow {
get {
TreeIter iter;
TreeModel model;
TreeSelection selection = treeView.Selection;
if (selection.GetSelected (out model, out iter)) {
TreePath[] path = selection.GetSelectedRows (out model);
return path[0].Indices[0]; // return selected row
}
else
return -1; // not selected
}
}
public TreeIter SelectedIter {
get {
TreeIter iter;
TreeModel model;
TreeSelection selection = treeView.Selection;
if (selection.GetSelected (out model, out iter))
return iter; // return seelcted iter
else
return TreeIter.Zero; // not selected
}
}
public TreeView View
{
get
{
return treeView;
}
}
public object DataSource
{
get
{
return dataSource;
}
set
{
dataSource = value;
}
}
public string DataMember
{
get
{
return dataMember;
}
set
{
dataMember = value;
}
}
public ListStore Store
{
get
{
return store;
}
}
public ArrayList Columns
{
get
{
return gridColumns;
}
}
public bool Editable {
get {
return editable; // not a good way to see if its editable or not
// because various columns could be editable and others non-editable
}
set {
editable = value;
if (value == true) {
for(int c = 0; c < gridColumns.Count; c++) {
DataGridColumn col = (DataGridColumn) gridColumns[c];
col.TreeViewColumn.Clickable = true;
col.Renderer.Mode = CellRendererMode.Editable;
col.Renderer.Editable = true;
}
treeView.RulesHint = true;
treeView.Selection.Mode = SelectionMode.Single;
}
else {
for(int c = 0; c < gridColumns.Count; c++) {
DataGridColumn col = (DataGridColumn) gridColumns[c];
col.TreeViewColumn.Clickable = false;
col.Renderer.Mode = CellRendererMode.Inert;
col.Renderer.Editable = false;
}
treeView.RulesHint = false;
treeView.Selection.Mode = SelectionMode.Single;
}
}
}
public int AddNew()
{
// TODO: need to check if resolved data source is not null
IBindingList b = (IBindingList) resolvedDataSource;
if (b.AllowNew) {
object obj = b.AddNew();
if (obj == null) {
//Console.Error.WriteLine("obj is null");
}
else {
//Console.Error.WriteLine("Type: " + obj.GetType().ToString());
bindrows.Add(obj);
TreeIter iter = NewRow();
for(int i = 0; i < gridColumns.Count; i++)
SetColumnValue (iter, i, String.Empty);
return bindrows.Count - 1;
}
}
return -1;
}
public int DeleteRow(int row)
{
if (row < 0)
return -1; // should throw an exception - out of range
TreeIter iter = TreeIter.Zero;
if (store.IterNthChild(out iter, row) == false)
return -1;
IBindingList b = (IBindingList) resolvedDataSource;
if (b.AllowRemove) {
IList list = (IList) resolvedDataSource;
bindrows.RemoveAt(row);
store.Remove (ref iter);
list.RemoveAt (row);
return row;
}
return -1;
}
// sets the column count. beware, it clears
// use this if you are going to load each column and row yourself
// instead of using DataBind() or DataLoad()
public void SetColumnCount (int columnCount)
{
Clear ();
dataMember = "";
dataSource = null;
GLib.GType[] theTypes = new GLib.GType[columnCount];
gridColumns = new ArrayList ();
for (int col = 0; col < columnCount; col++)
{
theTypes[col] = GLib.GType.String;
gridColumns.Add (new DataGridColumn ());
}
store.ColumnTypes = theTypes;
}
// load data from a data table or data set
public long DataBind ()
{
long rowsRetrieved = 0;
Clear ();
System.Object o = null;
o = GetResolvedDataSource (DataSource, DataMember);
resolvedDataSource = o;
IEnumerable ie = (IEnumerable) o;
ITypedList tlist = (ITypedList) o;
TreeIter iter = new TreeIter ();
PropertyDescriptorCollection pdc = tlist.GetItemProperties (new PropertyDescriptor[0]);
gridColumns = new ArrayList(pdc.Count);
// define the columns in the treeview store
// based on the schema of the result
GLib.GType[] theTypes = new GLib.GType[pdc.Count];
for (int col = 0; col < pdc.Count; col++) {
theTypes[col] = GLib.GType.String;
}
store.ColumnTypes = theTypes;
bindrows = new ArrayList();
int colndx = -1;
foreach (PropertyDescriptor pd in pdc) {
colndx ++;
DataGridColumn gridCol = new DataGridColumn ();
gridCol.ColumnName = pd.Name;
gridColumns.Add (gridCol);
}
bindrows = new ArrayList();
foreach (System.Object obj in ie) {
ICustomTypeDescriptor custom = (ICustomTypeDescriptor) obj;
PropertyDescriptorCollection properties = custom.GetProperties ();
bindrows.Add(obj);
rowsRetrieved ++;
iter = NewRow ();
int cv = 0;
foreach (PropertyDescriptor property in properties) {
object oPropValue = property.GetValue (obj);
string sPropValue = "";
if (oPropValue.GetType ().ToString ().Equals("System.Byte[]")) {
//sPropValue = SqlSharpGtk.GetHexString ((byte[]) oPropValue);
Console.Error.WriteLine("Byte[] value");
}
else
sPropValue = oPropValue.ToString ();
SetColumnValue (iter, cv, sPropValue);
cv++;
}
}
treeView.Model = store;
AutoCreateTreeViewColumns ();
return rowsRetrieved;
}
// borrowed from Mono's System.Web implementation
protected IEnumerable GetResolvedDataSource(object source, string member)
{
if (source != null && source is IListSource) {
IListSource src = (IListSource) source;
IList list = src.GetList ();
if (!src.ContainsListCollection) {
return list;
}
if (list != null && list is ITypedList) {
ITypedList tlist = (ITypedList) list;
PropertyDescriptorCollection pdc = tlist.GetItemProperties (new PropertyDescriptor[0]);
if (pdc != null && pdc.Count > 0) {
PropertyDescriptor pd = null;
if (member != null && member.Length > 0) {
pd = pdc.Find (member, true);
} else {
pd = pdc[0];
}
if (pd != null) {
object rv = pd.GetValue (list[0]);
if (rv != null && rv is IEnumerable) {
return (IEnumerable)rv;
}
}
throw new Exception ("ListSource_Missing_DataMember");
}
throw new Exception ("ListSource_Without_DataMembers");
}
}
if (source is IEnumerable) {
return (IEnumerable)source;
}
return null;
}
public void Clear ()
{
if (store != null)
{
store.Clear ();
store = null;
store = new ListStore (GLib.GType.String);
}
else
store = new ListStore (GLib.GType.String);
if (gridColumns != null)
{
for (int c = 0; c < gridColumns.Count; c++)
{
DataGridColumn gridCol = (DataGridColumn) gridColumns[c];
if (gridCol.TreeViewColumn != null)
{
treeView.RemoveColumn (gridCol.TreeViewColumn);
gridCol.TreeViewColumn = null;
}
}
gridColumns.Clear ();
gridColumns = null;
}
}
public TreeIter NewRow ()
{
return store.Append();
}
public void AddRow (object[] columnValues)
{
TreeIter iter = NewRow ();
for(int col = 0; col < columnValues.Length; col++) {
string cellValue = columnValues[col].ToString ();
SetColumnValue (iter, col, cellValue);
}
}
public void SetColumnValue (TreeIter iter, int column, string value)
{
GLib.Value cell = new GLib.Value (value);
store.SetValue (iter, column, cell);
}
public void SetColumnValue (TreeIter iter, int column, byte[] value)
{
//string svalue = SqlSharpGtk.GetHexString (value);
//SetColumnValue (iter, column, svalue);
}
private void AutoCreateTreeViewColumns ()
{
for(int col = 0; col < gridColumns.Count; col++) {
// escape underscore _ because it is used
// as the underline in menus and labels
StringBuilder name = new StringBuilder ();
foreach (char ch in ((DataGridColumn) gridColumns[col]).ColumnName) {
if (ch == '_')
name.Append ("__");
else
name.Append (ch);
}
TreeViewColumn tvc = CreateColumn (col, name.ToString ());
AppendColumn (tvc);
}
}
public int AppendColumn(TreeViewColumn tvc)
{
return treeView.AppendColumn (tvc);
}
private void TextCellEdited (object o, EditedArgs args)
{
IBindingList b = (IBindingList) resolvedDataSource;
if (b.AllowEdit) {
// ITypedList may help you figure out how to convert
// between different data types
// such as, how to display numbers, dates, etc...
TreePath path = new TreePath (args.Path);
TreeIter iter;
store.GetIter (out iter, path);
int i = path.Indices[0];
TreePath cpath;
string cellValue = args.NewText;
TreeViewColumn tvcolumn;
treeView.GetCursor (out cpath, out tvcolumn);
int c = 0;
for(c = 0; c < gridColumns.Count; c++) {
TreeViewColumn tvc = ((DataGridColumn) gridColumns[c]).TreeViewColumn;
if (tvcolumn == tvc) {
Console.Error.WriteLine("Column clicked: Column Name: " + tvcolumn.Title);
Console.Error.WriteLine(" Ordinal: " + c.ToString());
break;
}
}
if (c >= gridColumns.Count)
Console.Error.WriteLine("tv col not found");
ICustomTypeDescriptor custom = (ICustomTypeDescriptor) bindrows[i];
PropertyDescriptorCollection properties = custom.GetProperties ();
PropertyDescriptor pd = properties[c];
pd.SetValue(bindrows[i], cellValue);
Console.Error.WriteLine(" Row number: " + path.Indices[0].ToString());
Console.Error.WriteLine(" Cell Value: " + cellValue);
((IEditableObject) bindrows[i]).BeginEdit();
SetColumnValue(iter, c, cellValue);
((IEditableObject) bindrows[i]).EndEdit();
}
}
public TreeViewColumn CreateColumn (int columnNum, string columnName)
{
TreeViewColumn treeViewCol = new TreeViewColumn ();
CellRendererText renderer = new CellRendererText ();
treeViewCol.Clickable = true;
treeView.RulesHint = true;
treeView.Selection.Mode = SelectionMode.Single;
//treeView.Selection.Mode = SelectionMode.Multiple;
// Editable, Activatable, Inert
renderer.Mode = CellRendererMode.Editable;
//renderer.Family = "courier new";
renderer.Editable = true;
renderer.Edited += new EditedHandler (TextCellEdited);
treeViewCol.Title = columnName;
treeViewCol.PackStart (renderer, true);
treeViewCol.AddAttribute (renderer, "text", columnNum);
DataGridColumn gridCol = (DataGridColumn) gridColumns[columnNum];
gridCol.Renderer = renderer;
gridCol.TreeViewColumn = treeViewCol;
return treeViewCol;
}
}
}
-------------- next part --------------
// $ mcs /out:TestDataGrid.exe TestDataGrid.cs DataGrid.cs -pkg:gtk-sharp-2.0 /r:System.Data.dll
// TestDataGrid.cs
namespace Mono.Data.GtkSharp
{
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Data.SqlTypes;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Gdk;
using Gtk;
public class TestDataGrid
{
private DataTable table;
private Gtk.Window win;
private DataGrid grid;
//private TextView textView;
public static readonly string ApplicationName = "Gtk# DataGrid Test";
public TestDataGrid ()
{
CreateGui ();
}
public DataGrid Grid {
get {
return grid;
}
}
public void Show ()
{
win.ShowAll ();
}
public void CreateGui ()
{
win = new Gtk.Window (ApplicationName);
win.DeleteEvent += new Gtk.DeleteEventHandler (OnWindow_Delete);
win.BorderWidth = 4;
win.SetDefaultSize (600, 500);
VBox vbox = new VBox (false, 4);
win.Add (vbox);
MenuBar mb = CreateMenuBar ();
vbox.PackStart (mb, false, false, 0);
VPaned vpaned = new VPaned ();
vbox.PackStart (vpaned, true, true, 0);
grid = CreateOutputResultsDataGrid();
vpaned.Add1 (grid);
}
DataGrid CreateOutputResultsDataGrid ()
{
DataGrid grid = new DataGrid ();
//grid.View.ButtonReleaseEvent +=
// new Gtk.ButtonReleaseEventHandler (OnDataGridButtonRelease);
//grid.Editable = false;
return grid;
}
void OnWindow_Delete (object o, Gtk.DeleteEventArgs args)
{
QuitApplication();
}
void QuitApplication ()
{
Application.Quit ();
}
public static void DoEvents ()
{
while (Application.EventsPending ())
Application.RunIteration ();
}
public DataTable BuildDataTableSample()
{
table = new DataTable();
int maxColumns = 5;
int maxRows = 3;
for(int i = 0; i < maxColumns; i++) {
string columnName = String.Format("Column{0}", i);
table.Columns.Add(columnName);
}
for(int r = 0; r < maxRows; r++) {
DataRow row = table.NewRow();
for(int c = 0; c < table.Columns.Count; c++) {
string cellValue = String.Format("(Row{0},Column{1})", r, c);
row[c] = cellValue;
}
table.Rows.Add(row);
}
return table;
}
void OnMenu_DumpTable (object o, EventArgs args)
{
Console.Error.WriteLine("__=========== T a b l e D u m p =========__");
Console.Error.WriteLine("Row Count: " + table.Rows.Count.ToString());
for(int r = 0; r < table.Rows.Count; r++) {
DataRow row = table.Rows[r];
StringBuilder sb = new StringBuilder();
for(int c = 0; c < table.Columns.Count; c++) {
string s = row[c].ToString();
sb.Append(s);
sb.Append(" ");
}
Console.Error.WriteLine(sb.ToString());
}
Console.Error.WriteLine("=-----------------------------------------------=");
}
void OnMenu_Editable (object o, EventArgs args)
{
grid.Editable = !grid.Editable;
}
void OnMenu_AddNew (object o, EventArgs args)
{
AddNew();
}
void OnMenu_DeleteSelectedRow (object o, EventArgs args)
{
int selectedRow = 0;
selectedRow = grid.SelectedRow;
if (selectedRow >= 0)
grid.DeleteRow (selectedRow);
}
void AddNew()
{
grid.AddNew();
}
public MenuBar CreateMenuBar () {
MenuBar menuBar = new MenuBar ();
Menu menu;
MenuItem item;
MenuItem barItem;
menu = new Menu ();
item = new MenuItem ("Add Row");
item.Activated += new EventHandler (OnMenu_AddNew);
menu.Append (item);
item = new MenuItem ("Dump Table");
item.Activated += new EventHandler (OnMenu_DumpTable);
menu.Append (item);
item = new MenuItem ("Editable");
item.Activated += new EventHandler (OnMenu_Editable);
menu.Append (item);
item = new MenuItem ("Delete Selected Row");
item.Activated += new EventHandler (OnMenu_DeleteSelectedRow);
menu.Append (item);
barItem = new MenuItem ("Test");
barItem.Submenu = menu;
menuBar.Append (barItem);
return menuBar;
}
public static int Main (string[] args)
{
Application.Init ();
TestDataGrid test = new TestDataGrid ();
DataTable sampleTable = test.BuildDataTableSample();
test.Grid.DataSource = sampleTable;
test.Grid.DataBind();
test.Show ();
DoEvents ();
//test.Grid.Editable = false;
Application.Run ();
return 0;
}
}
}
More information about the Gtk-sharp-list
mailing list