Notifications
Clear all

[Closed] Open Code Project: Self Made Image Viewer

 lo1

Last update for now…
– Resize takes scrollbar width into account.
– Added 4 cell size option buttons.
– Label height is doubled if the text does not fit in one line.

Really fun control to play around with

global DGV_Icons
fn getGIFFiles = if DGV_Icons == undefined or true do
(
	local path = (getDir #ui) + "Icons\\"
	local files = getFiles (path + "*.bmp")
	DGV_Icons = for f in files collect 
	(
		local bmp = dotNetObject "System.Drawing.Bitmap" f
		bmp.tag = f
		bmp
	)
)
getGIFFiles()

global DataGridViewExtensionAssembly
fn CreateDataGridViewExtensionAssembly forceRecompile:on =
(
	if forceRecompile or not iskindof ::DataGridViewExtensionAssembly dotnetobject or (::DataGridViewExtensionAssembly.GetType()).name != "Assembly" do
	(
		source = ""
		source += "using System;
"
		source += "using System.Reflection;
"
		source += "using System.Runtime.InteropServices;
"
		source += "using System.Drawing;
"
		source += "using System.Windows.Forms;
"
		source += "namespace DataGridViewExtension
"
		source += "{
"
		source += "	public class Style
"
		source += "	{
"
		source += "		public void SetStyle(Control control, ControlStyles styles, bool newValue)
"
		source += "		{
"
		source += "			object[] args = { styles, newValue };
"
		source += "			typeof(Control).InvokeMember(\"SetStyle\",
"
		source += "					BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod,
"
		source += "					null, control, args);
"
		source += "		}
"
		source += "		public bool SetSelectable(Control control, bool newValue)
"
		source += "		{
"
		source += "			SetStyle(control, ControlStyles.Selectable, newValue);
"
		source += "			return newValue;
"
		source += "		}
"
		source += "		public void SetDoubleBuffer(Control control)
"
		source += "		{
"
		source += "			SetStyle(control, ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
"
		source += "		}
"
		source += "	}
"
		source += "	public class ImageTextCellColumn : DataGridViewImageColumn
"
		source += "	{
"
		source += "		private Boolean showLabel;
"
		source += "		private String label;
"
		source += "		private ContentAlignment labelAlign;
"
		source += "		private Color labelBackColor;
"
		source += "		private Color labelForeColor;
"
		source += "		public ImageTextCellColumn()
"
		source += "		{
"
		source += "			this.ShowLabel = true;
"
		source += "			this.LabelForeColor = Color.White;
"
		source += "			this.LabelBackColor = Color.FromArgb(100, Color.Black);
"
		source += "			this.CellTemplate = new ImageTextCell();
"
		source += "		}
"
		source += "		public override object Clone()
"
		source += "		{
"
		source += "			ImageTextCellColumn c = base.Clone() as ImageTextCellColumn;
"
		source += "			c.ShowLabel = this.showLabel;
"
		source += "			c.Label = this.label;
"
		source += "			c.LabelAlign = this.labelAlign;
"
		source += "			c.LabelForeColor = this.labelForeColor;
"
		source += "			c.LabelBackColor = this.labelBackColor;
"
		source += "			return c;
"
		source += "		}
"
		source += "		private ImageTextCell ImageTextCellTemplate
"
		source += "		{
"
		source += "			get { return this.CellTemplate as ImageTextCell; }
"
		source += "		}
"
		source += "		public Boolean ShowLabel
"
		source += "		{
"
		source += "			get { return this.showLabel; }
"
		source += "			set { this.showLabel = value; }
"
		source += "		}
"
		source += "		public String Label
"
		source += "		{
"
		source += "			get { return this.label; }
"
		source += "			set { this.label = value; }
"
		source += "		}
"
		source += "		public ContentAlignment LabelAlign
"
		source += "		{
"
		source += "			get { return this.labelAlign; }
"
		source += "			set { this.labelAlign = value; }
"
		source += "		}
"
		source += "		public Color LabelForeColor
"
		source += "		{
"
		source += "			get { return this.labelForeColor; }
"
		source += "			set { this.labelForeColor = value; }
"
		source += "		}
"
		source += "		public Color LabelBackColor
"
		source += "		{
"
		source += "			get { return this.labelBackColor; }
"
		source += "			set { this.labelBackColor = value; }
"
		source += "		}
"
		source += "	}
"
		source += "	public class ImageTextCell : DataGridViewImageCell
"
		source += "	{
"
		source += "		private Boolean showLabel;
"
		source += "		private String label;
"
		source += "		private Color labelBackColor;
"
		source += "		private Color labelForeColor;
"
		source += "		public ImageTextCell()
"
		source += "		{
"
		source += "			this.ShowLabel = true;
"
		source += "		}
"
		source += "		public override object Clone()
"
		source += "		{
"
		source += "			ImageTextCell c = base.Clone() as ImageTextCell;
"
		source += "			c.ShowLabel = this.showLabel;
"
		source += "			c.Label = this.label;
"
		source += "			c.LabelForeColor = this.labelForeColor;
"
		source += "			c.LabelBackColor = this.labelBackColor;
"
		source += "			return c;
"
		source += "		}
"
		source += "		public Boolean ShowLabel
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return showLabel; }
"
		source += "				else return (this.showLabel & this.ImageTextCellColumn.ShowLabel);
"
		source += "			}
"
		source += "			set { if (this.showLabel != value) { this.showLabel = value; } }
"
		source += "		}
"
		source += "		public String Label
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return label; }
"
		source += "				else if (this.label != null)
"
		source += "				{
"
		source += "					return this.label;
"
		source += "				}
"
		source += "				else
"
		source += "				{
"
		source += "					return this.ImageTextCellColumn.Label;
"
		source += "				}
"
		source += "			}
"
		source += "			set { if (this.label != value) { this.label = value; } }
"
		source += "		}
"
		source += "		public Color LabelForeColor
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return labelForeColor; }
"
		source += "				else if (this.labelForeColor != Color.Empty)
"
		source += "				{
"
		source += "					return this.labelForeColor;
"
		source += "				}
"
		source += "				else
"
		source += "				{
"
		source += "					return this.ImageTextCellColumn.LabelForeColor;
"
		source += "				}
"
		source += "			}
"
		source += "			set { if (this.labelForeColor != value) { this.labelForeColor = value; } }
"
		source += "		}
"
		source += "		public Color LabelBackColor
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return labelBackColor; }
"
		source += "				else if (this.labelBackColor != Color.Empty)
"
		source += "				{
"
		source += "					return this.labelBackColor;
"
		source += "				}
"
		source += "				else
"
		source += "				{
"
		source += "					return this.ImageTextCellColumn.LabelBackColor;
"
		source += "				}
"
		source += "			}
"
		source += "			set { if (this.labelBackColor != value) { this.labelBackColor = value; } }
"
		source += "		}
"
		source += "		protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
"
		source += "			DataGridViewElementStates cellState, object value, object formattedValue, string errorText,
"
		source += "			DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
"
		source += "		{
"
		source += "			// Paint the base content
"
		source += "			base.Paint(graphics, clipBounds, cellBounds, rowIndex,
"
		source += "				cellState, value, formattedValue, errorText,
"
		source += "				cellStyle, advancedBorderStyle, paintParts);
"
		source += "			if (this.ShowLabel && this.Label != null)
"
		source += "			{
"
		source += "				// Draw the image clipped to the cell.
"
		source += "				System.Drawing.Drawing2D.GraphicsContainer container = graphics.BeginContainer();
"
		source += "				SizeF ss = TextRenderer.MeasureText(this.Label, cellStyle.Font);
"
		source += "				if (ss.Width > this.Size.Width)
"
		source += "				{
"
		source += "					this.Label = this.Label.Insert((this.Label.Length/2),(\"-\"+Environment.NewLine));
"
		source += "					ss = TextRenderer.MeasureText(this.Label, cellStyle.Font);
"
		source += "				}
"
		source += "				ss = SizeF.Add(ss, new SizeF(0, 2));
"
		source += "				Single px = cellBounds.X;
"
		source += "				Single tx, py;
"
		source += "				switch (this.ImageTextCellColumn.LabelAlign)
"
		source += "				{
"
		source += "					case ContentAlignment.BottomCenter:
"
		source += "						{
"
		source += "							tx = (this.Size.Width - (ss.Width)) / 2 + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) + cellBounds.Y;
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.MiddleCenter:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) / 2 + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) / 2 + cellBounds.Y;
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.TopCenter:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) / 2 + px;
"
		source += "							py = cellBounds.Y;
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.TopLeft:
"
		source += "						{
"
		source += "							tx = px;
"
		source += "							py = cellBounds.Y;
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.BottomRight:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) + cellBounds.Y;
"
		source += "							break;
"
		source += "						}
"
		source += "					default:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) / 2 + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) + cellBounds.Y;
"
		source += "							break;
"
		source += "						}
"
		source += "				}
"
		source += "				Rectangle rect = new Rectangle((int)px, (int)py, (int)(cellBounds.Width-1), (int)ss.Height);
"
		source += "				graphics.SetClip(rect);
"
		source += "				graphics.FillRectangle(new SolidBrush(this.LabelBackColor), rect);
"
		source += "				graphics.DrawString(this.Label, cellStyle.Font, new SolidBrush(this.LabelForeColor), tx, py);
"
		source += "				graphics.EndContainer(container);
"
		source += "			}
"
		source += "		}
"
		source += "		public ImageTextCellColumn ImageTextCellColumn
"
		source += "		{
"
		source += "			get { return this.OwningColumn as ImageTextCellColumn; }
"
		source += "		}
"
		source += "	}
"
		source += "}
"
		
		local compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"  
		compilerParams.ReferencedAssemblies.AddRange #("System.dll","System.Windows.Forms.dll","System.Drawing.dll");  
		compilerParams.GenerateInMemory = true
		local compilerResults = (dotnetobject "Microsoft.CSharp.CSharpCodeProvider").CompileAssemblyFromSource compilerParams #(source)
		
		if (compilerResults.Errors.Count > 0 ) then
		(
			local errs = stringstream ""
			for i = 0 to (compilerResults.Errors.Count-1) do
			(
				local err = compilerResults.Errors.Item[i]
				format "Error:% Line:% Column:% %
" err.ErrorNumber err.Line err.Column err.ErrorText to:errs 
			)
			MessageBox (errs as string) title: "Errors encountered while compiling C# code"
			format "%
" errs
			undefined
		)
		else
		(
			DataGridViewExtensionAssembly = compilerResults.CompiledAssembly
		)
	)
)
CreateDataGridViewExtensionAssembly forceRecompile:on

fn initializeGridView =
(
	global maxCellWidth=150
	global gv = dotnetobject "DataGridView"
	
	local cc = DataGridViewExtensionAssembly.CreateInstance "DataGridViewExtension.Style"
	cc.SetDoubleBuffer gv
	
	local font = gv.font 
	gv.font = dotNetObject "System.Drawing.Font" font.FontFamily font.Size font.style.Bold
	
	global bc = DataGridViewExtensionAssembly.CreateInstance "DataGridViewExtension.ImageTextCellColumn"
	bc.LabelBackColor = (dotnetclass "System.Drawing.Color").FromARGB 255 (dotnetclass "System.Drawing.Color").Lime
	bc.LabelForeColor = (dotnetclass "System.Drawing.Color").FromARGB 255 (dotnetclass "System.Drawing.Color").Black
	bc.LabelAlign = bc.LabelAlign.BottomCenter
  
	local p = dotnetobject "System.Windows.Forms.Padding" 2
	p.Bottom = 16
	bc.DefaultCellStyle.Padding = p
	bc.ImageLayout = bc.ImageLayout.Normal
	bc.DefaultCellStyle.BackColor = bc.DefaultCellStyle.BackColor.Gray 
	bc.DefaultCellStyle.nullValue = undefined
)

fn reAdjustColumns =
(
	local ts=timestamp()
	local mem=heapfree
	local actualGVWidth = gv.width - (if gv.controls.item[1].visible then gv.controls.item[1].width else 0)
	print actualGVWidth
	if (local newColumnCount = amax (actualGVWidth/maxCellWidth) 1) != gv.ColumnCount do	
	(
		gv.SuspendLayout()	
		while newColumnCount > gv.ColumnCount do gv.columns.add (bc.clone())
		gv.ColumnCount = newColumnCount
		gv.RowCount = ceil (DGV_Icons.count as float/newColumnCount)
		gv.ResumeLayout()
	)
	format "Readjust Columns: Time: %ms, Memory: %kb
" (timestamp()-ts) ((mem-heapfree)/1000.0)
)

fn changeRowsHeight height =
(
	gv.SuspendLayout()
	for i = 1 to gv.Rows.Count do gv.Rows.item[i-1].height=height
	gv.ResumeLayout()	
)

fn CellSelectionChanged s e = 
(
	if s.selectedCells.count>0 do
	(
		if s.selectedCells.item[0].ToolTipText=="" then s.clearSelection() else
		format "button: %
" s.selectedCells.item[0].label
	)
)

fn CellFormatting s e =
(
	local c = e.rowindex*s.ColumnCount + e.ColumnIndex + 1
	local cell = s.rows.item[e.rowindex].cells.item[e.columnindex]
	if c <= DGV_Icons.count then
	(
		local bmp = DGV_Icons[c]		
		cell.ImageLayout = if cell.Size.width < bmp.width or cell.Size.height < bmp.height then cell.ImageLayout.Zoom	else cell.ImageLayout.Normal
		cell.ShowLabel = cell.ImageTextCellColumn.ShowLabel
		e.value = bmp
		cell.Description = cell.ToolTipText = bmp.tag
		cell.Label = c as string + " - " + (getfilenamefile bmp.tag)
	)
	else
	(
		e.value = undefined
		cell.Description = cell.ToolTipText = ""
		cell.ShowLabel = off
	)
)

try(destroyDialog denisTImageViewer)catch()
rollout denisTImageViewer "test" 
(
	dotNetControl panel "System.Windows.Forms.Panel" pos:[0,17]
	checkButton size1 "A" pos:[0,1] width:15 height:15
	checkButton size2 "B" pos:[0,1] width:15 height:15 checked:true
	checkButton size3 "C" pos:[0,1] width:15 height:15
	checkButton size4 "D" pos:[0,1] width:15 height:15
	
	on denisTImageViewer open do
	(
		size1.pos=[(denisTImageViewer.width-60),1]
		size2.pos=[(denisTImageViewer.width-45),1]
		size3.pos=[(denisTImageViewer.width-30),1]
		size4.pos=[(denisTImageViewer.width-15),1]
		panel.width = denisTImageViewer.width
		panel.height = denisTImageViewer.height-17
		initializeGridView()		
		dotNet.addEventHandler gv "CellFormatting" CellFormatting
		dotNet.addEventHandler gv "SelectionChanged" CellSelectionChanged
		local numCols = panel.width/maxCellWidth
		for k=1 to numCols do gv.columns.add (bc.clone())		
		gv.ColumnHeadersDefaultCellStyle.Alignment = gv.ColumnHeadersDefaultCellStyle.Alignment.MiddleCenter
		gv.ColumnHeadersVisible = gv.ShowEditingIcon = gv.RowHeadersVisible = gv.MultiSelect = off	
		gv.AllowUserToaddRows = gv.AllowUserToDeleteRows = gv.AllowUserToResizeColumns = gv.AllowUserToResizeRows = off
		gv.ReadOnly = gv.AutoSize = on
		gv.Dock = gv.Dock.Fill  
		gv.RowTemplate.Height = 150
		gv.AutoSizeColumnsMode = gv.AutoSizeColumnsMode.Fill
		gv.AutoSizeRowsMode = gv.AutoSizeRowsMode.None
		gv.RowHeadersWidthSizeMode = gv.RowHeadersWidthSizeMode.EnableResizing
		gv.RowCount = ((DGV_Icons.count)/numCols)
		gv.GridColor=gv.Gridcolor.black
		panel.controls.add gv
		reAdjustColumns()
	)
	
	on denisTImageViewer resized val do
	(
		panel.width=val[1]
		panel.height=val[2]-17
		size1.pos=[(val[1]-60),1]
		size2.pos=[(val[1]-45),1]
		size3.pos=[(val[1]-30),1]
		size4.pos=[(val[1]-15),1]
		reAdjustColumns()
	)
	
	on size1 changed state do (size1.state=on;size2.state=size3.state=size4.state=off; maxCellWidth=100;changeRowsHeight maxCellWidth; reAdjustColumns())
	on size2 changed state do (size2.state=on;size1.state=size3.state=size4.state=off; maxCellWidth=150;changeRowsHeight maxCellWidth; reAdjustColumns())
	on size3 changed state do (size3.state=on;size1.state=size2.state=size4.state=off; maxCellWidth=200;changeRowsHeight maxCellWidth; reAdjustColumns())
	on size4 changed state do (size4.state=on;size1.state=size2.state=size3.state=off; maxCellWidth=300;changeRowsHeight maxCellWidth; reAdjustColumns())
)
createDialog denisTImageViewer style:#(#style_titlebar, #style_border, #style_sysmenu,#style_resizing,#style_maximizebox) width:617 height:400

probably it will be better to support this option with graphics drawstring method using StringFormat
Does anyone want to take a look?

No big deal about the .tga stuff. I’ll prob. just stick with my current setup then.

Sweet updates btw.

 lo1

It’s one of those things where I think I’m really clever with some hacky code only to find out dotnet already has a built-in method that does exactly that.

I’ll take another look at drawstring…

i think that the label text alignment we can do with drawstring as well…

1 Reply
 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

I tried this, and while it worked, it actually made the code longer and messier, because the StringFormat’s alignment enumeration is not a content alignment enumeration (BottomCenter,TopRight,etc.) but a StringAlignment enumeration (Near, Center, Far), so it did not allow me to remove the text alignment checking from the switch.

Another issue is that DrawString does not seem to be able to wrap the line in the middle of the word, so it did not solve the problem of very long words (such as the max ui icons bmp’s) not being fully visible. I’ve read that the TextRenderer class has some options for this but didn’t fully explore.

I opted to stay with my previous method because it seems the shortest and most effective. I also jazzed it up with rounded edges and added code for all the content alignment options, feel free to try it.

I also made sure that when you change the icon size you get to more or less the same place you were looking at.

Thanks again for the push, I would have never dared to mess around with control extensions before, and I feel much more confident about starting to incorporate custom assemblies in my work.

global DGV_Icons
fn getGIFFiles = if DGV_Icons == undefined or true do
(
	local path = (getDir #ui) + "Icons\\"
	local files = getFiles (path + "*.bmp")
	DGV_Icons = for f in files collect 
	(
		local bmp = dotNetObject "System.Drawing.Bitmap" f
		bmp.tag = f
		bmp
	)
)
getGIFFiles()

global DataGridViewExtensionAssembly
fn CreateDataGridViewExtensionAssembly forceRecompile:on =
(
	if forceRecompile or not iskindof ::DataGridViewExtensionAssembly dotnetobject or (::DataGridViewExtensionAssembly.GetType()).name != "Assembly" do
	(
		source = ""
		source += "using System;
"
		source += "using System.Reflection;
"
		source += "using System.Runtime.InteropServices;
"
		source += "using System.Drawing;
"
		source += "using System.Windows.Forms;
"
		source += "namespace DataGridViewExtension
"
		source += "{
"
		source += "	public class Style
"
		source += "	{
"
		source += "		public void SetStyle(Control control, ControlStyles styles, bool newValue)
"
		source += "		{
"
		source += "			object[] args = { styles, newValue };
"
		source += "			typeof(Control).InvokeMember(\"SetStyle\",
"
		source += "					BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod,
"
		source += "					null, control, args);
"
		source += "		}
"
		source += "		public bool SetSelectable(Control control, bool newValue)
"
		source += "		{
"
		source += "			SetStyle(control, ControlStyles.Selectable, newValue);
"
		source += "			return newValue;
"
		source += "		}
"
		source += "		public void SetDoubleBuffer(Control control)
"
		source += "		{
"
		source += "			SetStyle(control, ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
"
		source += "		}
"
		source += "	}
"
		source += "	public class ImageTextCellColumn : DataGridViewImageColumn
"
		source += "	{
"
		source += "		private Boolean showLabel;
"
		source += "		private String label;
"
		source += "		private ContentAlignment labelAlign;
"
		source += "		private Color labelBackColor;
"
		source += "		private Color labelForeColor;
"
		source += "		public ImageTextCellColumn()
"
		source += "		{
"
		source += "			this.ShowLabel = true;
"
		source += "			this.LabelForeColor = Color.White;
"
		source += "			this.LabelBackColor = Color.FromArgb(100, Color.Black);
"
		source += "			this.CellTemplate = new ImageTextCell();
"
		source += "		}
"
		source += "		public override object Clone()
"
		source += "		{
"
		source += "			ImageTextCellColumn c = base.Clone() as ImageTextCellColumn;
"
		source += "			c.ShowLabel = this.showLabel;
"
		source += "			c.Label = this.label;
"
		source += "			c.LabelAlign = this.labelAlign;
"
		source += "			c.LabelForeColor = this.labelForeColor;
"
		source += "			c.LabelBackColor = this.labelBackColor;
"
		source += "			return c;
"
		source += "		}
"
		source += "		private ImageTextCell ImageTextCellTemplate
"
		source += "		{
"
		source += "			get { return this.CellTemplate as ImageTextCell; }
"
		source += "		}
"
		source += "		public Boolean ShowLabel
"
		source += "		{
"
		source += "			get { return this.showLabel; }
"
		source += "			set { this.showLabel = value; }
"
		source += "		}
"
		source += "		public String Label
"
		source += "		{
"
		source += "			get { return this.label; }
"
		source += "			set { this.label = value; }
"
		source += "		}
"
		source += "		public ContentAlignment LabelAlign
"
		source += "		{
"
		source += "			get { return this.labelAlign; }
"
		source += "			set { this.labelAlign = value; }
"
		source += "		}
"
		source += "		public Color LabelForeColor
"
		source += "		{
"
		source += "			get { return this.labelForeColor; }
"
		source += "			set { this.labelForeColor = value; }
"
		source += "		}
"
		source += "		public Color LabelBackColor
"
		source += "		{
"
		source += "			get { return this.labelBackColor; }
"
		source += "			set { this.labelBackColor = value; }
"
		source += "		}
"
		source += "	}
"
		source += "	public class ImageTextCell : DataGridViewImageCell
"
		source += "	{
"
		source += "		private Boolean showLabel;
"
		source += "		private String label;
"
		source += "		private Color labelBackColor;
"
		source += "		private Color labelForeColor;
"
		source += "		public ImageTextCell()
"
		source += "		{
"
		source += "			this.ShowLabel = true;
"
		source += "		}
"
		source += "		public override object Clone()
"
		source += "		{
"
		source += "			ImageTextCell c = base.Clone() as ImageTextCell;
"
		source += "			c.ShowLabel = this.showLabel;
"
		source += "			c.Label = this.label;
"
		source += "			c.LabelForeColor = this.labelForeColor;
"
		source += "			c.LabelBackColor = this.labelBackColor;
"
		source += "			return c;
"
		source += "		}
"
		source += "		public Boolean ShowLabel
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return showLabel; }
"
		source += "				else return (this.showLabel & this.ImageTextCellColumn.ShowLabel);
"
		source += "			}
"
		source += "			set { if (this.showLabel != value) { this.showLabel = value; } }
"
		source += "		}
"
		source += "		public String Label
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return label; }
"
		source += "				else if (this.label != null)
"
		source += "				{
"
		source += "					return this.label;
"
		source += "				}
"
		source += "				else
"
		source += "				{
"
		source += "					return this.ImageTextCellColumn.Label;
"
		source += "				}
"
		source += "			}
"
		source += "			set { if (this.label != value) { this.label = value; } }
"
		source += "		}
"
		source += "		public Color LabelForeColor
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return labelForeColor; }
"
		source += "				else if (this.labelForeColor != Color.Empty)
"
		source += "				{
"
		source += "					return this.labelForeColor;
"
		source += "				}
"
		source += "				else
"
		source += "				{
"
		source += "					return this.ImageTextCellColumn.LabelForeColor;
"
		source += "				}
"
		source += "			}
"
		source += "			set { if (this.labelForeColor != value) { this.labelForeColor = value; } }
"
		source += "		}
"
		source += "		public Color LabelBackColor
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return labelBackColor; }
"
		source += "				else if (this.labelBackColor != Color.Empty)
"
		source += "				{
"
		source += "					return this.labelBackColor;
"
		source += "				}
"
		source += "				else
"
		source += "				{
"
		source += "					return this.ImageTextCellColumn.LabelBackColor;
"
		source += "				}
"
		source += "			}
"
		source += "			set { if (this.labelBackColor != value) { this.labelBackColor = value; } }
"
		source += "		}
"
		source += "		protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
"
		source += "			DataGridViewElementStates cellState, object value, object formattedValue, string errorText,
"
		source += "			DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
"
		source += "		{
"
		source += "			// Paint the base content
"
		source += "			base.Paint(graphics, clipBounds, cellBounds, rowIndex,
"
		source += "				cellState, value, formattedValue, errorText,
"
		source += "				cellStyle, advancedBorderStyle, paintParts);
"
		source += "			if (this.ShowLabel && this.Label != null)
"
		source += "			{
"
		source += "				// Draw the image clipped to the cell.
"
		source += "				System.Drawing.Drawing2D.GraphicsContainer container = graphics.BeginContainer();
"
		source += "				SizeF ss = TextRenderer.MeasureText(this.Label, cellStyle.Font);
"
		source += "				if (ss.Width > this.Size.Width)
"
		source += "				{
"
		source += "					this.Label = this.Label.Insert((this.Label.Length/2),(\"-\"+Environment.NewLine));
"
		source += "					ss = TextRenderer.MeasureText(this.Label, cellStyle.Font);
"
		source += "				}
"
		source += "				ss = SizeF.Add(ss, new SizeF(0, 2));
"
		source += "				Single px = cellBounds.X;
"
		source += "				Single tx, py;
"
		source += "				Single gap = cellBounds.Width-ss.Width;
"
		source += "				RectangleF elRect;
"
		source += "				switch (this.ImageTextCellColumn.LabelAlign)
"
		source += "				{
"
		source += "					case ContentAlignment.BottomCenter:
"
		source += "						{
"
		source += "							tx = (this.Size.Width - (ss.Width)) / 2 + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,py,gap,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.MiddleCenter:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) / 2 + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) / 2 + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,py,gap,ss.Height);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.TopCenter:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) / 2 + px;
"
		source += "							py = cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,(py-ss.Height),gap,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.BottomLeft:
"
		source += "						{
"
		source += "							tx = px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px+ss.Width-cellBounds.Width,py,gap*2,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.MiddleLeft:
"
		source += "						{
"
		source += "							tx = px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) / 2 + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px+ss.Width-cellBounds.Width,py,gap*2,ss.Height);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.TopLeft:
"
		source += "						{
"
		source += "							tx = px;
"
		source += "							py = cellBounds.Y;
"
		source += "							elRect = new RectangleF(px+ss.Width-cellBounds.Width,(py-ss.Height),gap*2,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.BottomRight:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,py,gap*2,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.MiddleRight:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) / 2 + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,py,gap*2,ss.Height);
"
		source += "							break;
"
		source += "						}
"
		source += "					default:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) + px;
"
		source += "							py = cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,(py-ss.Height),gap*2,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "				}
"
		source += "				RectangleF rect = new RectangleF(tx, py, ss.Width, ss.Height);
"
		source += "				graphics.SetClip(new RectangleF(px,py,cellBounds.Width-1,ss.Height-1));
"
		source += " 				SolidBrush solBrush = new SolidBrush(this.Selected ? this.LabelForeColor : this.LabelBackColor);
"
		source += "				graphics.FillEllipse(solBrush, elRect);
"
		source += "				elRect.Offset((cellBounds.Width-gap),0.0F);
"
		source += "				graphics.FillEllipse(solBrush, elRect);
"
		source += "				graphics.FillRectangle(solBrush, rect);
"
		source += "				graphics.DrawString(this.Label, cellStyle.Font, new SolidBrush(this.Selected ? this.LabelBackColor : this.LabelForeColor),tx,py);
"
		source += "				graphics.EndContainer(container);
"
		source += "			}
"
		source += "		}
"
		source += "		public ImageTextCellColumn ImageTextCellColumn
"
		source += "		{
"
		source += "			get { return this.OwningColumn as ImageTextCellColumn; }
"
		source += "		}
"
		source += "	}
"
		source += "}
"
		
		local compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"  
		compilerParams.ReferencedAssemblies.AddRange #("System.dll","System.Windows.Forms.dll","System.Drawing.dll");  
		compilerParams.GenerateInMemory = true
		local compilerResults = (dotnetobject "Microsoft.CSharp.CSharpCodeProvider").CompileAssemblyFromSource compilerParams #(source)
		
		if (compilerResults.Errors.Count > 0 ) then
		(
			local errs = stringstream ""
			for i = 0 to (compilerResults.Errors.Count-1) do
			(
				local err = compilerResults.Errors.Item[i]
				format "Error:% Line:% Column:% %
" err.ErrorNumber err.Line err.Column err.ErrorText to:errs 
			)
			MessageBox (errs as string) title: "Errors encountered while compiling C# code"
			format "%
" errs
			undefined
		)
		else
		(
			DataGridViewExtensionAssembly = compilerResults.CompiledAssembly
		)
	)
)
CreateDataGridViewExtensionAssembly forceRecompile:on

fn initializeGridView =
(
	global maxCellWidth=150
	global gv = dotnetobject "DataGridView"
	
	local cc = DataGridViewExtensionAssembly.CreateInstance "DataGridViewExtension.Style"
	cc.SetDoubleBuffer gv
	
	local font = gv.font 
	gv.font = dotNetObject "System.Drawing.Font" font.FontFamily font.Size font.style.Bold
	
	global bc = DataGridViewExtensionAssembly.CreateInstance "DataGridViewExtension.ImageTextCellColumn"
	bc.LabelBackColor = (dotnetclass "System.Drawing.Color").FromARGB 255 50 120 150
	bc.LabelForeColor = (dotnetclass "System.Drawing.Color").FromARGB 255 200 255 255
	--bc.LabelAlign = bc.LabelAlign.BottomCenter
	--bc.LabelAlign = bc.LabelAlign.MiddleCenter
	--bc.LabelAlign = bc.LabelAlign.TopCenter
	--bc.LabelAlign = bc.LabelAlign.BottomLeft
	--bc.LabelAlign = bc.LabelAlign.MiddleLeft
	--bc.LabelAlign = bc.LabelAlign.TopLeft
	--bc.LabelAlign = bc.LabelAlign.BottomRight
	--bc.LabelAlign = bc.LabelAlign.BottomCenter
	bc.LabelAlign = bc.LabelAlign.BottomLeft
  
	local p = dotnetobject "System.Windows.Forms.Padding" 2
	p.Bottom = 16
	bc.DefaultCellStyle.Padding = p
	bc.ImageLayout = bc.ImageLayout.Normal
	bc.DefaultCellStyle.BackColor = bc.DefaultCellStyle.BackColor.FromARGB 255 150 180 180
	bc.DefaultCellStyle.nullValue = undefined
)

fn reAdjustColumns =
(
	local ts=timestamp()
	local mem=heapfree
	local actualGVWidth = gv.width - (if gv.controls.item[1].visible then gv.controls.item[1].width else 0)
	
	if (local newColumnCount = amax (actualGVWidth/maxCellWidth) 1) != gv.ColumnCount do	
	(
		if rowPercent==undefined do global rowPercent = (gv.FirstDisplayedScrollingRowIndex as float)/(gv.Rows.Count-1)
		gv.SuspendLayout()			
		while newColumnCount > gv.ColumnCount do gv.columns.add (bc.clone())
		gv.ColumnCount = newColumnCount
		gv.RowCount = ceil (DGV_Icons.count as float/newColumnCount)
		gv.FirstDisplayedScrollingRowIndex = floor(rowPercent*(gv.Rows.Count))
		gv.ResumeLayout()	
		rowPercent=undefined
	)
	format "Readjust Columns: Time: %ms, Memory: %kb
" (timestamp()-ts) ((mem-heapfree)/1000.0)
)

fn changeRowsHeight height =
(
	global rowPercent = (gv.FirstDisplayedScrollingRowIndex as float)/(gv.Rows.Count)
	gv.SuspendLayout()
	for i = 1 to gv.Rows.Count do gv.Rows.item[i-1].height=height
	gv.ResumeLayout()	

)

fn CellSelectionChanged s e = 
(
	if s.selectedCells.count>0 do
	(
		if s.selectedCells.item[0].ToolTipText=="" then s.clearSelection() else
		format "button: %
" s.selectedCells.item[0].label
	)
)

fn CellFormatting s e =
(
	local c = e.rowindex*s.ColumnCount + e.ColumnIndex + 1
	local cell = s.rows.item[e.rowindex].cells.item[e.columnindex]
	if c <= DGV_Icons.count then
	(
		local bmp = DGV_Icons[c]		
		cell.ImageLayout = if cell.Size.width < bmp.width or cell.Size.height < bmp.height then cell.ImageLayout.Zoom	else cell.ImageLayout.Normal
		cell.ShowLabel = cell.ImageTextCellColumn.ShowLabel
		e.value = bmp
		cell.Description = cell.ToolTipText = bmp.tag
		cell.Label = c as string + " - " + (substituteString (getfilenamefile bmp.tag) "_" " ")
	)
	else
	(
		e.value = undefined
		cell.Description = cell.ToolTipText = ""
		cell.ShowLabel = off
	)
)

try(destroyDialog denisTImageViewer)catch()
rollout denisTImageViewer "Image Viewer" 
(
	dotNetControl panel "System.Windows.Forms.Panel" pos:[0,17]
	checkButton size1 "A" pos:[0,1] width:15 height:15
	checkButton size2 "B" pos:[0,1] width:15 height:15 checked:true
	checkButton size3 "C" pos:[0,1] width:15 height:15
	checkButton size4 "D" pos:[0,1] width:15 height:15
	
	on denisTImageViewer open do
	(
		size1.pos=[(denisTImageViewer.width-60),1]
		size2.pos=[(denisTImageViewer.width-45),1]
		size3.pos=[(denisTImageViewer.width-30),1]
		size4.pos=[(denisTImageViewer.width-15),1]
		panel.width = denisTImageViewer.width
		panel.height = denisTImageViewer.height-17
		initializeGridView()		
		dotNet.addEventHandler gv "CellFormatting" CellFormatting
		dotNet.addEventHandler gv "SelectionChanged" CellSelectionChanged
		local numCols = panel.width/maxCellWidth
		for k=1 to numCols do gv.columns.add (bc.clone())		
		gv.ColumnHeadersDefaultCellStyle.Alignment = gv.ColumnHeadersDefaultCellStyle.Alignment.MiddleCenter
		gv.ColumnHeadersVisible = gv.ShowEditingIcon = gv.RowHeadersVisible = gv.MultiSelect = off	
		gv.AllowUserToaddRows = gv.AllowUserToDeleteRows = gv.AllowUserToResizeColumns = gv.AllowUserToResizeRows = off
		gv.ReadOnly = gv.AutoSize = on
		gv.Dock = gv.Dock.Fill  
		gv.RowTemplate.Height = 150
		gv.AutoSizeColumnsMode = gv.AutoSizeColumnsMode.Fill
		gv.AutoSizeRowsMode = gv.AutoSizeRowsMode.None
		gv.RowHeadersWidthSizeMode = gv.RowHeadersWidthSizeMode.EnableResizing
		gv.RowCount = ((DGV_Icons.count)/numCols)
		gv.GridColor=gv.Gridcolor.black
		panel.controls.add gv
		reAdjustColumns()
	)
	
	on denisTImageViewer resized val do
	(
		panel.width=val[1]
		panel.height=val[2]-17
		size1.pos=[(val[1]-60),1]
		size2.pos=[(val[1]-45),1]
		size3.pos=[(val[1]-30),1]
		size4.pos=[(val[1]-15),1]
		reAdjustColumns()
	)
	
	on size1 changed state do (size1.state=on;size2.state=size3.state=size4.state=off; maxCellWidth=100;changeRowsHeight maxCellWidth; reAdjustColumns())
	on size2 changed state do (size2.state=on;size1.state=size3.state=size4.state=off; maxCellWidth=150;changeRowsHeight maxCellWidth; reAdjustColumns())
	on size3 changed state do (size3.state=on;size1.state=size2.state=size4.state=off; maxCellWidth=200;changeRowsHeight maxCellWidth; reAdjustColumns())
	on size4 changed state do (size4.state=on;size1.state=size2.state=size3.state=off; maxCellWidth=300;changeRowsHeight maxCellWidth; reAdjustColumns())
)
createDialog denisTImageViewer style:#(#style_titlebar, #style_border, #style_sysmenu,#style_resizing,#style_maximizebox) width:617 height:400

 lo1

alright, last update from me…
–fixed some layout bugs
–files are no longer locked when shown
–improved smoothing of graphics rendering

try(destroyDialog denisTImageViewer)catch()
global DGV_Icons
fn getGIFFiles = if DGV_Icons == undefined or true do
(
	local path = (getDir #ui) + "Icons\\"
	local files = getFiles (path + "a*.bmp")
	DGV_Icons = for f in files collect 
	(
		local tempBmp = dotNetObject "System.Drawing.Bitmap" f
		local bmp = dotNetObject "System.Drawing.Bitmap" tempBmp
		tempBmp.dispose()
		bmp.tag = f
		bmp
	)
)
getGIFFiles()

global DataGridViewExtensionAssembly
fn CreateDataGridViewExtensionAssembly forceRecompile:on =
(
	if forceRecompile or not iskindof ::DataGridViewExtensionAssembly dotnetobject or (::DataGridViewExtensionAssembly.GetType()).name != "Assembly" do
	(
		source = ""
		source += "using System;
"
		source += "using System.Reflection;
"
		source += "using System.Runtime.InteropServices;
"
		source += "using System.Drawing;
"
		source += "using System.Windows.Forms;
"
		source += "namespace DataGridViewExtension
"
		source += "{
"
		source += "	public class Style
"
		source += "	{
"
		source += "		public void SetStyle(Control control, ControlStyles styles, bool newValue)
"
		source += "		{
"
		source += "			object[] args = { styles, newValue };
"
		source += "			typeof(Control).InvokeMember(\"SetStyle\",
"
		source += "					BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod,
"
		source += "					null, control, args);
"
		source += "		}
"
		source += "		public bool SetSelectable(Control control, bool newValue)
"
		source += "		{
"
		source += "			SetStyle(control, ControlStyles.Selectable, newValue);
"
		source += "			return newValue;
"
		source += "		}
"
		source += "		public void SetDoubleBuffer(Control control)
"
		source += "		{
"
		source += "			SetStyle(control, ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
"
		source += "		}
"
		source += "	}
"
		source += "	public class ImageTextCellColumn : DataGridViewImageColumn
"
		source += "	{
"
		source += "		private Boolean showLabel;
"
		source += "		private String label;
"
		source += "		private ContentAlignment labelAlign;
"
		source += "		private Color labelBackColor;
"
		source += "		private Color labelForeColor;
"
		source += "		public ImageTextCellColumn()
"
		source += "		{
"
		source += "			this.ShowLabel = true;
"
		source += "			this.LabelForeColor = Color.White;
"
		source += "			this.LabelBackColor = Color.Black;
"
		source += "			this.CellTemplate = new ImageTextCell();
"
		source += "		}
"
		source += "		public override object Clone()
"
		source += "		{
"
		source += "			ImageTextCellColumn c = base.Clone() as ImageTextCellColumn;
"
		source += "			c.ShowLabel = this.showLabel;
"
		source += "			c.Label = this.label;
"
		source += "			c.LabelAlign = this.labelAlign;
"
		source += "			c.LabelForeColor = this.labelForeColor;
"
		source += "			c.LabelBackColor = this.labelBackColor;
"
		source += "			return c;
"
		source += "		}
"
		source += "		private ImageTextCell ImageTextCellTemplate
"
		source += "		{
"
		source += "			get { return this.CellTemplate as ImageTextCell; }
"
		source += "		}
"
		source += "		public Boolean ShowLabel
"
		source += "		{
"
		source += "			get { return this.showLabel; }
"
		source += "			set { this.showLabel = value; }
"
		source += "		}
"
		source += "		public String Label
"
		source += "		{
"
		source += "			get { return this.label; }
"
		source += "			set { this.label = value; }
"
		source += "		}
"
		source += "		public ContentAlignment LabelAlign
"
		source += "		{
"
		source += "			get { return this.labelAlign; }
"
		source += "			set { this.labelAlign = value; }
"
		source += "		}
"
		source += "		public Color LabelForeColor
"
		source += "		{
"
		source += "			get { return this.labelForeColor; }
"
		source += "			set { this.labelForeColor = value; }
"
		source += "		}
"
		source += "		public Color LabelBackColor
"
		source += "		{
"
		source += "			get { return this.labelBackColor; }
"
		source += "			set { this.labelBackColor = value; }
"
		source += "		}
"
		source += "	}
"
		source += "	public class ImageTextCell : DataGridViewImageCell
"
		source += "	{
"
		source += "		private Boolean showLabel;
"
		source += "		private String label;
"
		source += "		private Color labelBackColor;
"
		source += "		private Color labelForeColor;
"
		source += "		public ImageTextCell()
"
		source += "		{
"
		source += "			this.ShowLabel = true;
"
		source += "		}
"
		source += "		public override object Clone()
"
		source += "		{
"
		source += "			ImageTextCell c = base.Clone() as ImageTextCell;
"
		source += "			c.ShowLabel = this.showLabel;
"
		source += "			c.Label = this.label;
"
		source += "			c.LabelForeColor = this.labelForeColor;
"
		source += "			c.LabelBackColor = this.labelBackColor;
"
		source += "			return c;
"
		source += "		}
"
		source += "		public Boolean ShowLabel
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return showLabel; }
"
		source += "				else return (this.showLabel & this.ImageTextCellColumn.ShowLabel);
"
		source += "			}
"
		source += "			set { if (this.showLabel != value) { this.showLabel = value; } }
"
		source += "		}
"
		source += "		public String Label
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return label; }
"
		source += "				else if (this.label != null)
"
		source += "				{
"
		source += "					return this.label;
"
		source += "				}
"
		source += "				else
"
		source += "				{
"
		source += "					return this.ImageTextCellColumn.Label;
"
		source += "				}
"
		source += "			}
"
		source += "			set { if (this.label != value) { this.label = value; } }
"
		source += "		}
"
		source += "		public Color LabelForeColor
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return labelForeColor; }
"
		source += "				else if (this.labelForeColor != Color.Empty)
"
		source += "				{
"
		source += "					return this.labelForeColor;
"
		source += "				}
"
		source += "				else
"
		source += "				{
"
		source += "					return this.ImageTextCellColumn.LabelForeColor;
"
		source += "				}
"
		source += "			}
"
		source += "			set { if (this.labelForeColor != value) { this.labelForeColor = value; } }
"
		source += "		}
"
		source += "		public Color LabelBackColor
"
		source += "		{
"
		source += "			get
"
		source += "			{
"
		source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return labelBackColor; }
"
		source += "				else if (this.labelBackColor != Color.Empty)
"
		source += "				{
"
		source += "					return this.labelBackColor;
"
		source += "				}
"
		source += "				else
"
		source += "				{
"
		source += "					return this.ImageTextCellColumn.LabelBackColor;
"
		source += "				}
"
		source += "			}
"
		source += "			set { if (this.labelBackColor != value) { this.labelBackColor = value; } }
"
		source += "		}
"
		source += "		protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
"
		source += "			DataGridViewElementStates cellState, object value, object formattedValue, string errorText,
"
		source += "			DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
"
		source += "		{
"
		source += "			// Paint the base content
"
		source += "			base.Paint(graphics, clipBounds, cellBounds, rowIndex,
"
		source += "				cellState, value, formattedValue, errorText,
"
		source += "				cellStyle, advancedBorderStyle, paintParts);
"
		source += "			if (this.ShowLabel && this.Label != null)
"
		source += "			{
"
		source += "				// Draw the image clipped to the cell.
"
		source += "				System.Drawing.Drawing2D.GraphicsContainer container = graphics.BeginContainer();
"
		source += "				graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
"
		source += "				SizeF ss = TextRenderer.MeasureText(this.Label, cellStyle.Font);
"
		source += "				if (ss.Width > this.Size.Width)
"
		source += "				{
"
		source += "					this.Label = this.Label.Insert((this.Label.Length/2),(\"-\"+Environment.NewLine));
"
		source += "					ss = TextRenderer.MeasureText(this.Label, cellStyle.Font);
"
		source += "				}
"
		source += "				ss = SizeF.Add(ss, new SizeF(0, 2));
"
		source += "				Single px = cellBounds.X;
"
		source += "				Single tx, py;
"
		source += "				Single gap = cellBounds.Width-ss.Width;
"
		source += "				RectangleF elRect;
"
		source += "				switch (this.ImageTextCellColumn.LabelAlign)
"
		source += "				{
"
		source += "					case ContentAlignment.BottomCenter:
"
		source += "						{
"
		source += "							tx = (this.Size.Width - (ss.Width)) / 2 + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,py,gap,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.MiddleCenter:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) / 2 + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) / 2 + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,py,gap,ss.Height);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.TopCenter:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) / 2 + px;
"
		source += "							py = cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,(py-ss.Height),gap,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.BottomLeft:
"
		source += "						{
"
		source += "							tx = px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px+ss.Width-cellBounds.Width,py,gap*2,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.MiddleLeft:
"
		source += "						{
"
		source += "							tx = px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) / 2 + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px+ss.Width-cellBounds.Width,py,gap*2,ss.Height);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.TopLeft:
"
		source += "						{
"
		source += "							tx = px;
"
		source += "							py = cellBounds.Y;
"
		source += "							elRect = new RectangleF(px+ss.Width-cellBounds.Width,(py-ss.Height),gap*2,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.BottomRight:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,py,gap*2,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "					case ContentAlignment.MiddleRight:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) / 2 + px;
"
		source += "							py = (cellBounds.Height - ss.Height-1) + cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,py,gap*2,ss.Height);
"
		source += "							break;
"
		source += "						}
"
		source += "					default:
"
		source += "						{
"
		source += "							tx = (cellBounds.Width - ss.Width) + px;
"
		source += "							py = cellBounds.Y;
"
		source += "							elRect = new RectangleF(px,(py-ss.Height),gap*2,ss.Height*2);
"
		source += "							break;
"
		source += "						}
"
		source += "				}
"
		source += "				graphics.SetClip(new RectangleF(px,py,cellBounds.Width-1,ss.Height-1));
"
		source += " 				SolidBrush solBrush = new SolidBrush(this.Selected ? this.LabelForeColor : this.LabelBackColor);
"
		source += "				graphics.FillEllipse(solBrush, elRect);
"
		source += "				elRect.Offset((cellBounds.Width-gap),0.0F);
"
		source += "				graphics.FillEllipse(solBrush, elRect);
"
		source += "				graphics.FillRectangle(solBrush, new RectangleF(tx, py, ss.Width, ss.Height));
"
		source += "				graphics.DrawString(this.Label, cellStyle.Font, new SolidBrush(this.Selected ? this.LabelBackColor : this.LabelForeColor),tx,py);
"
		source += "				graphics.EndContainer(container);
"
		source += "			}
"
		source += "		}
"
		source += "		public ImageTextCellColumn ImageTextCellColumn
"
		source += "		{
"
		source += "			get { return this.OwningColumn as ImageTextCellColumn; }
"
		source += "		}
"
		source += "	}
"
		source += "}
"
		
		local compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"  
		compilerParams.ReferencedAssemblies.AddRange #("System.dll","System.Windows.Forms.dll","System.Drawing.dll");  
		compilerParams.GenerateInMemory = true
		local compilerResults = (dotnetobject "Microsoft.CSharp.CSharpCodeProvider").CompileAssemblyFromSource compilerParams #(source)
		
		if (compilerResults.Errors.Count > 0 ) then
		(
			local errs = stringstream ""
			for i = 0 to (compilerResults.Errors.Count-1) do
			(
				local err = compilerResults.Errors.Item[i]
				format "Error:% Line:% Column:% %
" err.ErrorNumber err.Line err.Column err.ErrorText to:errs 
			)
			MessageBox (errs as string) title: "Errors encountered while compiling C# code"
			format "%
" errs
			undefined
		)
		else
		(
			DataGridViewExtensionAssembly = compilerResults.CompiledAssembly
		)
	)
)
CreateDataGridViewExtensionAssembly forceRecompile:off

fn initializeGridView =
(
	global rowPercent
	global maxCellWidth=150
	global gv = dotnetobject "DataGridView"
	
	local cc = DataGridViewExtensionAssembly.CreateInstance "DataGridViewExtension.Style"
	cc.SetDoubleBuffer gv
	
	local font = gv.font 
	gv.font = dotNetObject "System.Drawing.Font" font.FontFamily font.Size font.style.Bold
	
	global bc = DataGridViewExtensionAssembly.CreateInstance "DataGridViewExtension.ImageTextCellColumn"
	bc.LabelBackColor = (dotnetclass "System.Drawing.Color").FromARGB 255 50 120 150
	bc.LabelForeColor = (dotnetclass "System.Drawing.Color").FromARGB 255 200 255 255
	--bc.LabelAlign = bc.LabelAlign.BottomCenter
	--bc.LabelAlign = bc.LabelAlign.MiddleCenter
	--bc.LabelAlign = bc.LabelAlign.TopCenter
	bc.LabelAlign = bc.LabelAlign.BottomLeft
	--bc.LabelAlign = bc.LabelAlign.MiddleLeft
	--bc.LabelAlign = bc.LabelAlign.TopLeft
	--bc.LabelAlign = bc.LabelAlign.BottomRight
	--bc.LabelAlign = bc.LabelAlign.MiddleRight
	--bc.LabelAlign = bc.LabelAlign.TopRight
  
	local p = dotnetobject "System.Windows.Forms.Padding" 2
	p.Bottom = 16
	bc.DefaultCellStyle.Padding = p
	bc.ImageLayout = bc.ImageLayout.Normal
	bc.DefaultCellStyle.BackColor = bc.DefaultCellStyle.BackColor.FromARGB 255 150 180 180
	bc.DefaultCellStyle.nullValue = undefined
)

fn reAdjustColumns =
(
	local ts=timestamp()
	local mem=heapfree
	local actualGVWidth = gv.width - (if gv.controls.item[1].visible then gv.controls.item[1].width else 0)
	
	if (local newColumnCount = amax ((actualGVWidth as float/maxCellWidth) as integer) 1) != gv.ColumnCount do	
	(
		if rowPercent==undefined do rowPercent = (gv.FirstDisplayedScrollingRowIndex as float)/(gv.Rows.Count-1)
		gv.SuspendLayout()		
		while newColumnCount > gv.ColumnCount do gv.columns.add (bc.clone())
		gv.ColumnCount = newColumnCount
		for i = 1 to gv.ColumnCount do gv.Columns.item[i-1].width=floor(actualGVWidth as float/newColumnCount)
		gv.RowCount = ceil (DGV_Icons.count as float/newColumnCount)
		gv.FirstDisplayedScrollingRowIndex = floor(rowPercent*(gv.Rows.Count))
		gv.ResumeLayout()	
		rowPercent=undefined
	)
	format "Readjust Columns: Time: %ms, Memory: %kb
" (timestamp()-ts) ((mem-heapfree)/1000.0)
)

fn changeRowsHeight height =
(
	rowPercent = (gv.FirstDisplayedScrollingRowIndex as float)/(gv.Rows.Count)
	gv.SuspendLayout()
	for i = 1 to gv.Rows.Count do gv.Rows.item[i-1].height=height
	gv.RowTemplate.Height = height
	gv.ResumeLayout()	

)

fn CellSelectionChanged s e = 
(
	if s.selectedCells.count>0 do
	(
		if s.selectedCells.item[0].ToolTipText=="" then s.clearSelection() else
		format "button: %
" s.selectedCells.item[0].label
	)
)

fn CellFormatting s e =
(
	local c = e.rowindex*s.ColumnCount + e.ColumnIndex + 1
	local cell = s.rows.item[e.rowindex].cells.item[e.columnindex]
	if c <= DGV_Icons.count then
	(
		local cellBmp = DGV_Icons[c]
		cell.ImageLayout = if cell.Size.width < cellBmp.width or cell.Size.height < cellBmp.height then cell.ImageLayout.Zoom	else cell.ImageLayout.Normal
		cell.ShowLabel = cell.ImageTextCellColumn.ShowLabel
		e.value = cellBmp
		cell.Description = cell.ToolTipText = cellBmp.tag
		cell.Label = c as string + " - " + (substituteString (getfilenamefile cellBmp.tag) "_" " ")
	)
	else
	(
		e.value = undefined
		cell.Description = cell.ToolTipText = ""
		cell.ShowLabel = off
	)
)

rollout denisTImageViewer "Image Viewer" 
(
	dotNetControl panel "System.Windows.Forms.Panel" pos:[0,17]
	checkButton size1 "A" pos:[0,1] width:15 height:15
	checkButton size2 "B" pos:[0,1] width:15 height:15 checked:true
	checkButton size3 "C" pos:[0,1] width:15 height:15
	checkButton size4 "D" pos:[0,1] width:15 height:15
	
	on denisTImageViewer open do
	(
		size1.pos=[(denisTImageViewer.width-60),1]
		size2.pos=[(denisTImageViewer.width-45),1]
		size3.pos=[(denisTImageViewer.width-30),1]
		size4.pos=[(denisTImageViewer.width-15),1]
		panel.width = denisTImageViewer.width
		panel.height = denisTImageViewer.height-17
		initializeGridView()
		dotNet.addEventHandler gv "CellFormatting" CellFormatting
		dotNet.addEventHandler gv "SelectionChanged" CellSelectionChanged
		local numCols = panel.width/maxCellWidth
		for k=1 to numCols do gv.columns.add (bc.clone())
		gv.ColumnHeadersVisible = gv.ShowEditingIcon = gv.RowHeadersVisible = gv.MultiSelect = off	
		gv.AllowUserToaddRows = gv.AllowUserToDeleteRows = gv.AllowUserToResizeColumns = gv.AllowUserToResizeRows = off
		gv.ReadOnly = gv.AutoSize = on
		gv.Dock = gv.Dock.Fill
		gv.RowTemplate.Height = 150
		gv.AutoSizeColumnsMode = gv.AutoSizeColumnsMode.Fill
		gv.AutoSizeRowsMode = gv.AutoSizeRowsMode.None
		gv.RowHeadersWidthSizeMode = gv.RowHeadersWidthSizeMode.EnableResizing
		gv.RowCount = ceil (DGV_Icons.count as float/numCols)
		gv.GridColor=gv.Gridcolor.black
		panel.controls.add gv
		reAdjustColumns()
	)
	
	on denisTImageViewer resized val do
	(
		panel.width=val[1]
		panel.height=val[2]-17
		size1.pos=[(val[1]-60),1]
		size2.pos=[(val[1]-45),1]
		size3.pos=[(val[1]-30),1]
		size4.pos=[(val[1]-15),1]
		reAdjustColumns()
	)
	
	on size1 changed state do (size1.state=on;size2.state=size3.state=size4.state=off; maxCellWidth=100;changeRowsHeight maxCellWidth; reAdjustColumns())
	on size2 changed state do (size2.state=on;size1.state=size3.state=size4.state=off; maxCellWidth=150;changeRowsHeight maxCellWidth; reAdjustColumns())
	on size3 changed state do (size3.state=on;size1.state=size2.state=size4.state=off; maxCellWidth=200;changeRowsHeight maxCellWidth; reAdjustColumns())
	on size4 changed state do (size4.state=on;size1.state=size2.state=size3.state=off; maxCellWidth=300;changeRowsHeight maxCellWidth; reAdjustColumns())
		
	on denisTImageViewer close do
	(
		for f in DGV_Icons do f.dispose()
		gv.dispose()
		bc.dispose()
	)
)
createDialog denisTImageViewer style:#(#style_titlebar, #style_border, #style_sysmenu,#style_resizing,#style_maximizebox) width:617 height:400

what is it? How do you do it?

3 Replies
 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

in the paint event I added

graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality

It was not relevant earlier because only a rectangle was being painted, but the ellipse borders look better with antialiasing.

(@denist)
Joined: 11 months ago

Posts: 0

interesting. i don’t have MAX to try. could you try to add smoothing before the painting of base content? does it change the quality of image scale? also you can try to change interpolation mode:

graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;

if it changes the quality we can add new property to control it.
high quality rendering might slow the control down but make thumbnails smoother.

 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

yeah, that totally works. I don’t see any hit in performance either.

Here is a time for update!
New version of ImageTextCellColumn has HighQuality property (for image scale issue for example), and uses StringFormat for label text alignment and word(char) wrapping (see documentation for StringFormat).


global DGV_Icons
fn getGIFFiles = if DGV_Icons == undefined or true do
(
--	local path = (getDir #ui) + "Icons\\"
--	local files = getFiles (path + "*.ico")

	local path = (getDir #ui) + "Ribbon\\Tooltips\\Images\\"
	local files = getFiles (path + "*.gif")

--	local path = (getDir #ui) + "Ribbon\\Icons\\Modeling\\"
--	local files = getFiles (path + "*.bmp")
	DGV_Icons = for f in files collect 
	(
		bmp = dotNetObject "System.Drawing.Bitmap" f
		bmp.tag = f
		bmp
	)
)
getGIFFiles()

global DataGridViewExtensionAssembly
fn CreateDataGridViewExtensionAssembly forceRecompile:on =
(
	if forceRecompile or not iskindof ::DataGridViewExtensionAssembly dotnetobject or (::DataGridViewExtensionAssembly.GetType()).name != "Assembly" do
	(

source = ""
source += "using System;
"
source += "using System.Reflection;
"
source += "using System.Runtime.InteropServices;
"
source += "using System.Drawing;
"
source += "using System.Windows.Forms;
"
source += "namespace DataGridViewExtension
"
source += "{
"
source += "	public class Style
"
source += "	{
"
source += "		public void SetStyle(Control control, ControlStyles styles, bool newValue)
"
source += "		{
"
source += "			object[] args = { styles, newValue };
"
source += "			typeof(Control).InvokeMember(\"SetStyle\",
"
source += "					BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod,
"
source += "					null, control, args);
"
source += "		}
"
source += "		public bool SetSelectable(Control control, bool newValue)
"
source += "		{
"
source += "			SetStyle(control, ControlStyles.Selectable, newValue);
"
source += "			return newValue;
"
source += "		}
"
source += "		public void SetDoubleBuffer(Control control)
"
source += "		{
"
source += "			SetStyle(control, ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
"
source += "		}
"
source += "	}
"
source += "	public class ImageTextCellColumn : DataGridViewImageColumn
"
source += "	{
"
source += "		private Boolean showLabel;
"
source += "		private Boolean highQuality;
"
source += "		private String label;
"
source += "		private StringFormat stringFormat;
"
source += "		private Color labelBackColor;
"
source += "		private Color labelForeColor;
"
source += "		public ImageTextCellColumn()
"
source += "		{
"
source += "			this.ShowLabel = true;
"
source += "			this.HighQuality = false;
"
source += "			this.StringFormat = new StringFormat();
"
source += "			this.LabelForeColor = Color.White;
"
source += "			this.LabelBackColor = Color.FromArgb(100, Color.Black);
"
source += "			this.CellTemplate = new ImageTextCell();
"
source += "		}
"
source += "		public override object Clone()
"
source += "		{
"
source += "			ImageTextCellColumn c = base.Clone() as ImageTextCellColumn;
"
source += "			c.ShowLabel = this.showLabel;
"
source += "			c.HighQuality = this.highQuality;
"
source += "			c.Label = this.label;
"
source += "			c.StringFormat = this.stringFormat;
"
source += "			c.LabelForeColor = this.labelForeColor;
"
source += "			c.LabelBackColor = this.labelBackColor;
"
source += "			return c;
"
source += "		}
"
source += "		private ImageTextCell ImageTextCellTemplate
"
source += "		{
"
source += "			get { return this.CellTemplate as ImageTextCell; }
"
source += "		}
"
source += "		public Boolean ShowLabel
"
source += "		{
"
source += "			get { return this.showLabel; }
"
source += "			set { this.showLabel = value; }
"
source += "		}
"
source += "		public Boolean HighQuality
"
source += "		{
"
source += "			get { return this.highQuality; }
"
source += "			set { this.highQuality = value; }
"
source += "		}
"
source += "		public String Label
"
source += "		{
"
source += "			get { return this.label; }
"
source += "			set { this.label = value; }
"
source += "		}
"
source += "		public StringFormat StringFormat
"
source += "		{
"
source += "			get { return this.stringFormat; }
"
source += "			set { this.stringFormat = value; }
"
source += "		}
"
source += "		public Color LabelForeColor
"
source += "		{
"
source += "			get { return this.labelForeColor; }
"
source += "			set { this.labelForeColor = value; }
"
source += "		}
"
source += "		public Color LabelBackColor
"
source += "		{
"
source += "			get { return this.labelBackColor; }
"
source += "			set { this.labelBackColor = value; }
"
source += "		}
"
source += "	}
"
source += "	public class ImageTextCell : DataGridViewImageCell
"
source += "	{
"
source += "		private Boolean showLabel;
"
source += "		private String label;
"
source += "		private Color labelBackColor;
"
source += "		private Color labelForeColor;
"
source += "		public ImageTextCell()
"
source += "		{
"
source += "			this.ShowLabel = true;
"
source += "		}
"
source += "		public override object Clone()
"
source += "		{
"
source += "			ImageTextCell c = base.Clone() as ImageTextCell;
"
source += "			c.ShowLabel = this.showLabel;
"
source += "			c.Label = this.label;
"
source += "			c.LabelForeColor = this.labelForeColor;
"
source += "			c.LabelBackColor = this.labelBackColor;
"
source += "			return c;
"
source += "		}
"
source += "		public Boolean ShowLabel
"
source += "		{
"
source += "			get
"
source += "			{
"
source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return showLabel; }
"
source += "				else return (this.showLabel & this.ImageTextCellColumn.ShowLabel);
"
source += "			}
"
source += "			set { if (this.showLabel != value) { this.showLabel = value; } }
"
source += "		}
"
source += "		public String Label
"
source += "		{
"
source += "			get
"
source += "			{
"
source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return label; }
"
source += "				else if (this.label != null)
"
source += "				{
"
source += "					return this.label;
"
source += "				}
"
source += "				else
"
source += "				{
"
source += "					return this.ImageTextCellColumn.Label;
"
source += "				}
"
source += "			}
"
source += "			set { if (this.label != value) { this.label = value; } }
"
source += "		}
"
source += "		public Color LabelForeColor
"
source += "		{
"
source += "			get
"
source += "			{
"
source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return labelForeColor; }
"
source += "				else if (this.labelForeColor != Color.Empty)
"
source += "				{
"
source += "					return this.labelForeColor;
"
source += "				}
"
source += "				else
"
source += "				{
"
source += "					return this.ImageTextCellColumn.LabelForeColor;
"
source += "				}
"
source += "			}
"
source += "			set { if (this.labelForeColor != value) { this.labelForeColor = value; } }
"
source += "		}
"
source += "		public Color LabelBackColor
"
source += "		{
"
source += "			get
"
source += "			{
"
source += "				if (this.OwningColumn == null || this.ImageTextCellColumn == null) { return labelBackColor; }
"
source += "				else if (this.labelBackColor != Color.Empty)
"
source += "				{
"
source += "					return this.labelBackColor;
"
source += "				}
"
source += "				else
"
source += "				{
"
source += "					return this.ImageTextCellColumn.LabelBackColor;
"
source += "				}
"
source += "			}
"
source += "			set { if (this.labelBackColor != value) { this.labelBackColor = value; } }
"
source += "		}
"
source += "		protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
"
source += "			DataGridViewElementStates cellState, object value, object formattedValue, string errorText,
"
source += "			DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
"
source += "		{
"
source += "			// Paint the base content
"
source += "			if (this.ImageTextCellColumn.HighQuality)
"
source += "			{
"
source += "				graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
"
source += "				graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
"
source += "			}
"
source += "			base.Paint(graphics, clipBounds, cellBounds, rowIndex,
"
source += "				cellState, value, formattedValue, errorText,
"
source += "				cellStyle, advancedBorderStyle, paintParts);
"
source += "			if (this.ShowLabel && this.Label != null)
"
source += "			{
"
source += "				// Draw the image clipped to the cell.
"
source += "				System.Drawing.Drawing2D.GraphicsContainer container = graphics.BeginContainer();
"
source += "				SizeF ss = graphics.MeasureString(this.Label, cellStyle.Font,
"
source += "					new SizeF(cellBounds.Width, cellBounds.Height), this.ImageTextCellColumn.StringFormat);
"
source += "				ss = new SizeF((float)Math.Round(ss.Width), (float)Math.Round(ss.Height));
"
source += "				ss = SizeF.Add(ss, new SizeF(0, 2));
"
source += "				Single px = cellBounds.X;
"
source += "				Single py = cellBounds.Y;
"
source += "				switch (this.ImageTextCellColumn.StringFormat.LineAlignment)
"
source += "				{
"
source += "					case StringAlignment.Far:
"
source += "						{
"
source += "							py = (cellBounds.Height - ss.Height) + cellBounds.Y;
"
source += "							break;
"
source += "						}
"
source += "					case StringAlignment.Center:
"
source += "						{
"
source += "							py = (cellBounds.Height - ss.Height) / 2 + cellBounds.Y;
"
source += "							break;
"
source += "						}
"
source += "				}
"
source += "				Rectangle rect = new Rectangle((int)px, (int)py, (int)cellBounds.Width, (int)ss.Height);
"
source += "				graphics.SetClip(rect);
"
source += "				graphics.FillRectangle(new SolidBrush(this.LabelBackColor), rect);
"
source += "				graphics.DrawString(this.Label, cellStyle.Font, new SolidBrush(this.LabelForeColor), 
"
source += "					(RectangleF)cellBounds, this.ImageTextCellColumn.StringFormat);
"
source += "				graphics.EndContainer(container);
"
source += "			}
"
source += "		}
"
source += "		public ImageTextCellColumn ImageTextCellColumn
"
source += "		{
"
source += "			get { return this.OwningColumn as ImageTextCellColumn; }
"
source += "		}
"
source += "	}
"
source += "}
"

		csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
		compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"

		compilerParams.ReferencedAssemblies.AddRange #("System.dll","System.Windows.Forms.dll","System.Drawing.dll");

		compilerParams.GenerateInMemory = true
		compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
		
		if (compilerResults.Errors.Count > 0 ) then
		(
			errs = stringstream ""
			for i = 0 to (compilerResults.Errors.Count-1) do
			(
				err = compilerResults.Errors.Item[i]
				format "Error:% Line:% Column:% %
" err.ErrorNumber err.Line err.Column err.ErrorText to:errs 
			)
			MessageBox (errs as string) title: "Errors encountered while compiling C# code"
			format "%
" errs
			undefined
		)
		else
		(
			DataGridViewExtensionAssembly = compilerResults.CompiledAssembly
--			DataGridViewExtensionAssembly.CreateInstance "ImageTextCellColumn"
		)
	)
)
--global DataGridViewExtension = if DataGridViewExtension == undefined then CreateDataGridViewExtensionAssembly() else DataGridViewExtension
global DataGridViewExtensionOps = CreateDataGridViewExtensionAssembly forceRecompile:on

try(form.close()) catch()
form = dotnetobject "MaxCustomControls.Maxform"
form.Text = "DataGridView ImageTextCell"	

form.StartPosition = form.StartPosition.Manual
form.Location = dotnetobject "System.Drawing.Point" 200 100
form.Size = dotnetobject "System.Drawing.Size" 800 660

addc = dotnetobject "Button"
addc.text = "Add Column"
addc.Dock = addc.Dock.Top	

delc = dotnetobject "Button"
delc.text = "Remove Column"
delc.Dock = addc.Dock.Top	
	
addr = dotnetobject "Button"
addr.text = "Add Row"
addr.Dock = addc.Dock.Top	

delr = dotnetobject "Button"
delr.text = "Remove Row"
delr.Dock = addc.Dock.Top	

gv = dotnetobject "DataGridView"
cc = DataGridViewExtensionAssembly.CreateInstance "DataGridViewExtension.Style"
cc.SetDoubleBuffer gv
font = gv.font 
gv.font = dotNetObject "System.Drawing.Font" font.FontFamily font.Size font.style.Bold
	
bc = DataGridViewExtensionAssembly.CreateInstance "DataGridViewExtension.ImageTextCellColumn"
bc.LabelBackColor = (dotnetclass "System.Drawing.Color").FromARGB 70 (dotnetclass "System.Drawing.Color").DarkRed
bc.LabelForeColor = (dotnetclass "System.Drawing.Color").FromARGB 200 (dotnetclass "System.Drawing.Color").Black
--bc.LabelForeColor = (dotnetclass "System.Drawing.Color").White
--bc.LabelBackColor = (dotnetclass "System.Drawing.Color").Transparent

--bc.StringFormat = dotnetobject "System.Drawing.StringFormat"
bc.HighQuality = on
bc.StringFormat.Alignment = bc.StringFormat.Alignment.Center
bc.StringFormat.LineAlignment = bc.StringFormat.LineAlignment.Far

p = dotnetobject "System.Windows.Forms.Padding" 2
p.Bottom = 16
bc.DefaultCellStyle.Padding = p
bc.ImageLayout = bc.ImageLayout.Normal

/* Flat Settings */
bc.DefaultCellStyle.BackColor = bc.DefaultCellStyle.BackColor.Beige 
--bc.FlatStyle = bc.FlatStyle.Flat 

fn addColumn s e =
(
	gv = s.parent.controls.item[0]
	gv.SuspendLayout()
	gv.columns.add (bc.clone())
	gv.ResumeLayout()
)	
dotNet.addEventHandler addc "Click" addColumn
fn removeColumn s e =
(
	gv = s.parent.controls.item[0]
	gv.SuspendLayout()
	gv.ColumnCount = amax (gv.ColumnCount-1) 1
	gv.ResumeLayout()
)	
dotNet.addEventHandler delc "Click" removeColumn
fn addRow s e =
(
	gv = s.parent.controls.item[0]
	gv.SuspendLayout()
	s.parent.controls.item[0].RowCount += 1
	gv.ResumeLayout()
)	
dotNet.addEventHandler addr "Click" addRow
fn removeRow s e =
(
	gv = s.parent.controls.item[0]
	gv.SuspendLayout()
	gv.RowCount = amax (gv.RowCount-1) 1
	gv.ResumeLayout()
)	
dotNet.addEventHandler delr "Click" removeRow

fn CellClick s e = 
(
	cell = s.rows.item[e.rowindex].cells.item[e.columnindex]
	format "button: %
" cell.value
)
fn CellFormatting s e =
(
	c = e.rowindex*s.ColumnCount + e.ColumnIndex
	i = mod c DGV_Icons.count
	bmp = DGV_Icons[i+1]
	
	cell = s.rows.item[e.rowindex].cells.item[e.columnindex]
	cell.ImageLayout = if cell.Size.width < bmp.width or cell.Size.height < bmp.height then cell.ImageLayout.Zoom
		else cell.ImageLayout.Normal
	if not cell.ImageTextCellColumn.ShowLabel do cell.ShowLabel = off
	e.value = bmp
	cell.Description = bmp.tag
	cell.Label = ((c+1) as integer) as string + " - " + (filenamefrompath cell.Description) --+ (cell.Description)
	cell.ToolTipText = bmp.tag
)
fn updateGridView s e = 
(
	gv.SuspendLayout()
	for r=0 to s.RowCount-1 do for i=0 to s.ColumnCount-1 do
	(
		cell = s.rows.item[r].cells.item[i]
		v = r*s.ColumnCount + i
	)
	gv.ResumeLayout()
)
fn changeGridViewRowHeight gv height = 
(
	gv.SuspendLayout()
	gv.RowTemplate.Height = height
	for r=0 to gv.RowCount-1 do gv.rows.item[r].Height = height
	gv.ResumeLayout()
)

gv.ColumnHeadersDefaultCellStyle.Alignment = gv.ColumnHeadersDefaultCellStyle.Alignment.MiddleCenter
gv.ReadOnly = on
gv.MultiSelect = on
	
dotNet.addEventHandler gv "CellFormatting" CellFormatting
dotNet.addEventHandler gv "ColumnAdded" updateGridView
dotNet.addEventHandler gv "ColumnRemoved" updateGridView
dotNet.addEventHandler gv "RowsAdded" updateGridView
dotNet.addEventHandler gv "RowsRemoved" updateGridView
dotNet.addEventHandler gv "CellClick" CellClick

gv.Dock = gv.Dock.Fill

gv.RowTemplate.Height = 160
gv.AutoSize = on
	
gv.AutoSizeColumnsMode = gv.AutoSizeColumnsMode.Fill
--gv.AutoSizeRowsMode = gv.AutoSizeRowsMode.AllCells
gv.AutoSizeRowsMode = gv.AutoSizeRowsMode.None
gv.RowHeadersWidthSizeMode = gv.RowHeadersWidthSizeMode.EnableResizing
	
for k=1 to 4 do gv.columns.add (bc.clone())

gv.RowCount = 251

gv.ColumnHeadersVisible = gv.ShowEditingIcon = gv.RowHeadersVisible = off	
gv.AllowUserToaddRows = gv.AllowUserToDeleteRows = gv.AllowUserToResizeColumns = off
gv.AllowUserToResizeRows = on

form.controls.addrange #(gv, delr, addr, delc, addc)

form.showmodeless()

Page 2 / 2