Laden...

MultiColumnListBox

Erstellt von Programmierhans vor 18 Jahren Letzter Beitrag vor 18 Jahren 5.771 Views
Programmierhans Themenstarter:in
4.221 Beiträge seit 2005
vor 18 Jahren
MultiColumnListBox

Controls die niemand braucht... hier ein Neues 🙂

MultiColumnListBox ist im Prinzip eine normale ListBox, welche ich aber ein "wenig" aufgepumpt habe.

Aenderungen gegenüber der normalen ListBox.

Zugelassene DataSource:

  • DataTable
  • DataView

Designer Unterstützung der Erweiterungen:

  • Keine

Darstellung von Bildern

  • Ja müssen als ByteArray auf der DataTable vorhanden sein

Verwendung:

  • wie eine normale Listbox

Abgehängte Properties

  • DisplayMember

Grundsätzlich werden immer alle Columns der DatenQuelle angezeigt. Höhe der Items = ItemHeight....

Spalten können ausgeblendet (Visible=false) und in der Breite verändert werden (Width=neuerWert).

Absolut wichtig:

Aenderungen der Breite oder Sichtbarkeit der Spalten kann erst NACH dem setzen der DataSource durchgeführt werden.

So und nun den Code für das Control:


using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.IO;

namespace myCSHARPControls
{
	/// <summary>
	/// Summary description for ListBoxMultiColumn.
	/// </summary>
	public class ListBoxMultiColumn:ListBox
	{
		private SizableDataColumn[] _Columns=null;
		private DataView _DataView=null;
		private CurrencyManager _CM=null;

		public ListBoxMultiColumn()
		{
			this.DrawMode=DrawMode.OwnerDrawFixed;
		}

		public new object DataSource
		{
			get{return base.DataSource;}
			set
			{
				base.DataSource=value;
				if (value!=null)
				{
					this._Columns=null;
					this._CM=this.BindingContext[this.DataSource,string.Empty] as CurrencyManager;
					this._DataView=this._CM.List as DataView;
				}
				else
				{
					this._Columns=null;
					this._CM=null;
					this._DataView=null;
				}
			}
		}

		public SizableDataColumn[] Columns
		{
			get
			{
				if (this._Columns==null)
				{
					if (this._DataView!=null)
					{
						
							DataRowView drv=this._DataView[0];
							DataTable dt=this._DataView.Table;
							this._Columns=new SizableDataColumn[dt.Columns.Count];
							for (int i=0;i<dt.Columns.Count;i++)
							{
								DataColumn dtc=dt.Columns[i];
								this._Columns[i]=new SizableDataColumn(dtc.ColumnName,i,75);
							}
						
					}
				}
				return this._Columns;
			}
		}


		/// <summary>
		/// Draws the Item (Image)
		/// </summary>
		/// <param name="e">the DrawItemEventArgs</param>
		protected override void OnDrawItem(DrawItemEventArgs e)
		{
			e.DrawBackground();
			if (e.Index>-1 && this.Items.Count>e.Index)
			{
				DataRowView itm=this.Items[e.Index] as DataRowView;
				if (itm!=null)
				{
					DataRow rw=itm.Row;
					int offset=0;
					for (int i=0;i<this.Columns.Length;i++)
					{
						object value=rw[i];
						SizableDataColumn sdc=this.Columns[i];
						if (sdc.Visible)
						{

							Rectangle rectToPaint=new Rectangle(offset,this.ItemHeight*e.Index,sdc.Width,this.ItemHeight);
						
							if (value.GetType()==typeof(byte[]))
							{
								Image img=null;
								//Image
								using (MemoryStream ms=new MemoryStream(value as byte[]))
								{
									img=new Bitmap(ms);
									float factor=Math.Max((float)img.Width/(float)rectToPaint.Width,(float)img.Height/(float)rectToPaint.Height);
									e.Graphics.DrawImage(img,offset,this.ItemHeight*e.Index,(float)img.Width/factor,(float)img.Height/factor);
								}
							
							}
							else
							{
								//sonstwas
								StringFormat sf=new StringFormat();
								sf.Trimming=StringTrimming.EllipsisCharacter;
								e.Graphics.DrawString(value.ToString(),this.Font,new SolidBrush(this.ForeColor),rectToPaint,sf);
							}
							offset+=sdc.Width;
						}
					}
				}
			}
			e.DrawFocusRectangle();
			base.OnDrawItem(e);
		}
		
	}
}


Zusätzlich benötigte Klasse


using System;
using System.Data;

namespace myCSHARPControls
{
	/// <summary>
	/// Summary description for SizableDataColumn.
	/// </summary>
	public class SizableDataColumn
	{
		private readonly string _Name;
		private readonly int _Index;
		private int _Width=0;
		private bool _Visible=true;

		public SizableDataColumn(string pName, int pIndex, int pWidth)
		{
			this._Name=pName;
			this._Index=pIndex;
			this._Width=pWidth;
		}

		public string Name
		{get{return this._Name;}}

		public int Index
		{get{return this._Index;}}

		public int Width
		{
			get{return this._Width;}
			set{this._Width=value;}
		}

		public bool Visible
		{
			get{return this._Visible;}
			set{this._Visible=value;}
		}
	}
}


TestCode:


using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;

namespace myCSHARPControlsTester
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private myCSHARPControls.ListBoxMultiColumn listBoxMultiColumn1;
		private myCSHARPControlsTester.DsTestData dsTestData1;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.listBoxMultiColumn1 = new myCSHARPControls.ListBoxMultiColumn();
			this.dsTestData1 = new myCSHARPControlsTester.DsTestData();
			((System.ComponentModel.ISupportInitialize)(this.dsTestData1)).BeginInit();
			this.SuspendLayout();
			// 
			// listBoxMultiColumn1
			// 
			this.listBoxMultiColumn1.Dock = System.Windows.Forms.DockStyle.Fill;
			this.listBoxMultiColumn1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
			this.listBoxMultiColumn1.ItemHeight = 75;
			this.listBoxMultiColumn1.Location = new System.Drawing.Point(0, 0);
			this.listBoxMultiColumn1.Name = "listBoxMultiColumn1";
			this.listBoxMultiColumn1.Size = new System.Drawing.Size(656, 379);
			this.listBoxMultiColumn1.TabIndex = 0;
			// 
			// dsTestData1
			// 
			this.dsTestData1.DataSetName = "DsTestData";
			this.dsTestData1.Locale = new System.Globalization.CultureInfo("en-US");
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(656, 437);
			this.Controls.Add(this.listBoxMultiColumn1);
			this.Name = "Form1";
			this.Text = "Form1";
			this.Load += new System.EventHandler(this.Form1_Load);
			((System.ComponentModel.ISupportInitialize)(this.dsTestData1)).EndInit();
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

		private void Form1_Load(object sender, System.EventArgs e)
		{
			DsTestData.TestTableDataTable dtTest=this.dsTestData1.TestTable;

			Image img1=Image.FromFile(@"C:\WINNT\Web\Wallpaper\Snow Trees.jpg");
			Image img2=Image.FromFile(@"C:\WINNT\Web\Wallpaper\Ocean wave.jpg");
			Image img3=Image.FromFile(@"C:\WINNT\Web\Wallpaper\Paradise.jpg");
			Image img4=Image.FromFile(@"C:\WINNT\Web\Wallpaper\Purple sponge.jpg");

			byte[] bytesImg1=null;
			byte[] bytesImg2=null;
			byte[] bytesImg3=null;
			byte[] bytesImg4=null;

			using(MemoryStream ms=new MemoryStream())
			{
				img1.Save(ms,System.Drawing.Imaging.ImageFormat.Bmp);
				bytesImg1=ms.GetBuffer();
			}
			
			using(MemoryStream ms=new MemoryStream())
			{
				img2.Save(ms,System.Drawing.Imaging.ImageFormat.Bmp);
				bytesImg2=ms.GetBuffer();
			}

			using(MemoryStream ms=new MemoryStream())
			{
				img3.Save(ms,System.Drawing.Imaging.ImageFormat.Bmp);
				bytesImg3=ms.GetBuffer();
			}

			using(MemoryStream ms=new MemoryStream())
			{
				img4.Save(ms,System.Drawing.Imaging.ImageFormat.Bmp);
				bytesImg4=ms.GetBuffer();
			}

            dtTest.AddTestTableRow("A",1,bytesImg1,bytesImg2,"B");
			dtTest.AddTestTableRow("C",2,bytesImg3,bytesImg4,"D");

			dtTest.AcceptChanges();

			img1.Dispose();
			img2.Dispose();
			img3.Dispose();
			img4.Dispose();

//DataSource zuweisen
this.listBoxMultiColumn1.DataSource=dtTest;
//über Columns[index] könnt ihr die Werte verändern
//Column ausblenden
this.listBoxMultiColumn1.Columns[0].Visible=false;
//Breite verändern
this.listBoxMultiColumn1.Columns[3].Width=200;

//ValueField nicht vergessen wenn der Wert auch noch gebunden werden soll.
		}
	}
}


Der TestCode sieht unnötig kompliziert aus (damit ihr nicht selber ne Testumgebung aufbauen müsst).... wichtig sind eigentlich nur diese Zeilen des TestCodes:


//DataSource zuweisen
this.listBoxMultiColumn1.DataSource=dtTest;
//über Columns[index] könnt ihr die Werte verändern
//Column ausblenden
this.listBoxMultiColumn1.Columns[0].Visible=false;
//Breite verändern
this.listBoxMultiColumn1.Columns[3].Width=200;

//ValueField nicht vergessen wenn der Wert auch noch gebunden werden soll.

So und nun viel Vergnügen

Euer Programmierhans

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...