Datagridtextmulticolumn : type de colonne text multiligne à l'affichage

Contenu du snippet

Vous avez peut-être remarqué mais le DataGridTextBoxColumn n'affiche qu'une seule ligne, même si la hauteur de la ligne est suffisante. Par contre lors de l'édition, on peut tout voir.

Voici donc le code de la classe DataGridTextMultiColumn dérivée de DataGridColumnStyle qui permet un affichage multiligne en toute circonstance.

Source / Exemple :


public class DataGridTextMultiColumn : DataGridColumnStyle 
{
	private TextBox _TextBox = new TextBox();
	
	private bool isEditing;
		public DataGridTextMultiColumn() : base() 
	{
		_TextBox.Visible = false;
		_TextBox.Multiline = true;
	}
		protected override void Abort(int rowNum)
	{
		isEditing = false;
		_TextBox.TextChanged -= 
			new EventHandler(_TextBoxValueChanged);
		Invalidate();
	}
		protected override bool Commit
		(CurrencyManager dataSource, int rowNum) 
	{
		_TextBox.Bounds = Rectangle.Empty;
        
		_TextBox.TextChanged -= 
			new EventHandler(_TextBoxValueChanged);
			if (!isEditing)
			return true;
			isEditing = false;
			try 
		{
			string value = _TextBox.Text;
			SetColumnValueAtRow(dataSource, rowNum, value);
		} 
		catch (Exception) 
		{
			Abort(rowNum);
			return false;
		}

		Invalidate();
		return true;
	}

	protected override void Edit(
		CurrencyManager source, 
		int rowNum,
		Rectangle bounds, 
		bool readOnly,
		string instantText, 
		bool cellIsVisible) 
	{
	string value = GetColumnValueAtRow(source, rowNum).ToString();
		if (cellIsVisible) 
		{
			_TextBox.Bounds = new Rectangle
				(bounds.X + 2, bounds.Y + 2, 
				bounds.Width - 4, bounds.Height - 4);
			_TextBox.Text = value;
			_TextBox.Visible = true;
			_TextBox.TextChanged += 
				new EventHandler(_TextBoxValueChanged);
		} 
		else 
		{
			_TextBox.Text = value;
			_TextBox.Visible = false;
		}

		if (_TextBox.Visible)
			DataGridTableStyle.DataGrid.Invalidate(bounds);
	}

	protected override Size GetPreferredSize(
		Graphics g, 
		object value) 
	{
		return new Size(100, _TextBox.PreferredHeight + 4);
	}

	protected override int GetMinimumHeight() 
	{
		return _TextBox.PreferredHeight + 4;
	}

	protected override int GetPreferredHeight(Graphics g, object value) 
	{
		return _TextBox.PreferredHeight + 4;
	}

	protected override void Paint(Graphics g, 
		Rectangle bounds, 
		CurrencyManager source, 
		int rowNum) 
	{
		Paint(g, bounds, source, rowNum, false);
	}
		protected override void Paint(
		Graphics g, 
		Rectangle bounds,
		CurrencyManager source, 
		int rowNum,
		bool alignToRight) 
	{
		Paint(g,bounds, source, rowNum, 	Brushes.Red, Brushes.Blue, alignToRight);
	}
	protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum,Brush backBrush, Brush foreBrush, bool alignToRight) 
	{
	string str = GetColumnValueAtRow(source, rowNum).ToString();
	Rectangle rect = bounds;
	g.FillRectangle(backBrush,rect);
	rect.Offset(0, 2);
	rect.Height -= 2;
	g.DrawString(str, this.DataGridTableStyle.DataGrid.Font, foreBrush, rect);
	}

	protected override void SetDataGridInColumn(DataGrid value) 
	{
		base.SetDataGridInColumn(value);
		if (_TextBox.Parent != null) 
		{
		_TextBox.Parent.Controls.Remove (_TextBox);
		}
		if (value != null) 
		{
		value.Controls.Add(_TextBox);
		}
	}

	private void _TextBoxValueChanged(object sender, EventArgs e) 
	{
		this.isEditing = true;
		base.ColumnStartedEditing(_TextBox);
	}
}

Conclusion :


Je me suis servi de l'exemple de code trouvé sur le MSDN qui faisait la même chose pour un DataTimePicker.

Pour s'en servir :
DataGridTableStyle sty = new DataGridTableStyle();
DataGridTextMultiColumn colDescription = new DataGridTextMultiColumn();

//TableStyle
sty.PreferredRowHeight = 80;
sty.ReadOnly = true;

Colonne description
colDescription.MappingName = "Description";
colDescription.Width = 225;

//Datagrid
dtg.TableStyles.Clear();
dtg.TableStyles.Add(sty);
dtg.DataSource = ds;
dtg.DataMember = "Source";

Comme quand on défini un DataGrid à la main

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.