Re: Custom controls in datagrid

From: CJ (cjohns_at_telkomsa.net)
Date: 06/02/04


Date: Wed, 2 Jun 2004 09:47:52 +0200

In article <euVCX0BSEHA.2468@TK2MSFTNGP11.phx.gbl>, ernest@gesora.com
says...
> > 1) I lose the first character typed into the richtextbox: the user
> > clicks the cell and the richtextbox gets focus, but the first character
> > is swallowed and only the second character on is shown.
>
> Maybe you didn't take in consideration the parameter instantText of the
> method Edit.

This looked interesting, but doesn't seem to help. This is the sequence
of events:

click in cell:
Edit called, with instantText and cell value ""
Edit called, with instantText and cell value ""

type first char:
richtextboxtextchanged event is fired, and handler is called
Edit called, with instantText and cell value ""
richtextboxtextchanged, and handler is called
no character appears

type 2nd char:
richtextboxtextchanged, and handler is called
richtextboxtextchanged, and handler is called
and char appears
        
> > 2) There is some odd behaviour if the user first types in the second
> > column of the first row instead of the first column (there are only 2
> > columns). If you edit cell (2, 1) (row, column), then edit cell (1, 1),
> > and then go on to edit one of the cells in the newly created 2nd row,
> > the contents of (1,1) are lost. It appears that if cell (2,1) is edited
> > before cell (1,1), the commit event is not fired.
>
> Did you call the ColumnStartedEditing when the editing begins ?
> Does your control disapear when the cell loses the focus ?
> Are you sure your Commit executes every time the data in the cell is
> changed?

Yes I do call ColumnStartedEditing (in the richtextboxtextchanged
handler), and no, I'm not sure that the commit is executed when it needs
to be. But I can't control that - all I'm doing is inheriting from
DataGridTextBoxColumn and overriding the necessary methods (see code
below).

>
> > 3) Is there any way to allow text to be dropped onto the automatically
> > added bottom row without having to click on it first? I'm guessing not,
> > because the cells don't even contain the null text, so it seems as
> > though they haven't really been created yet (as such).
>
> You should know that the cells in a column(in the grid) are just
> pictures(rectangles with some text and/or picture inside), nothing else.
> A cell "gets alive" just in the moment it gets the focus. In that moment(and
> only in that moment), a control(a TextBox, CheckBox, DateTimePicker) becomes
> visible and occupies the space of the cell and sits over the grid.
> If a cell doesn't have the focus, then the surface of the cell is in fact
> the surface of the grid.

Okay, that makes sense.

Thanks for your help - I think that part of the problem is that I don't
really understand what goes on in a Datagrid (but I wouldn't think I'd
need to, just to do something this simple based on an msdn example!).

public class DataGridRichTextDragBoxColumn : DataGridTextBoxColumn
        {
                public RichTextDragBox rtdb = new RichTextDragBox();
                // The isEditing field tracks whether or not the user is
                // editing data with the hosted control.
                private bool isEditing;

                public DataGridRichTextDragBoxColumn() : base()
                {
                        rtdb.Visible = false;
                        this.NullText = "";
                }

                protected override void Abort(int rowNum)
                {
                        isEditing = false;
                        rtdb.TextChanged -= new EventHandler
(RichTextDragBoxChanged);
                        Invalidate();
                }

                protected override bool Commit(CurrencyManager dataSource,
int rowNum)
                {
                        rtdb.Bounds = Rectangle.Empty;
         
                        rtdb.TextChanged -= new EventHandler
(RichTextDragBoxChanged);

                        if (!isEditing)
                                return true;

                        isEditing = false;

                        try
                        {
                                string val = rtdb.Text;
                                SetColumnValueAtRow(dataSource, rowNum, val);
                        }
                        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 val;

                        object o = GetColumnValueAtRow(source, rowNum);
                        if (Convert.IsDBNull(o))
                                val = this.NullText;
                        else
                                val = (string)o;

                        Console.WriteLine("IT: _" + instantText + "_ val: "
+ val);

                        if (cellIsVisible)
                        {

                                rtdb.Bounds = new Rectangle
                                        (bounds.X + 2, bounds.Y + 2,
                                        bounds.Width - 4, bounds.Height - 4);
                                rtdb.TextChanged += new EventHandler
(RichTextDragBoxChanged);
                                rtdb.Text = val;
                                rtdb.Visible = true;
                                rtdb.BringToFront();
                                rtdb.Focus();
                        }
                        else
                        {
                                rtdb.Text = val;
                                rtdb.Visible = false;
                        }

                        if (rtdb.Visible)
                                DataGridTableStyle.DataGrid.Invalidate
(bounds);

                }
                private void RichTextDragBoxChanged(object sender,
EventArgs e)
                {
                        Console.WriteLine("DragBoxChanged");
                        this.isEditing = true;
                        base.ColumnStartedEditing(rtdb);
                }

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

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

                protected override int GetPreferredHeight(Graphics g,
object val)
                {
                        return rtdb.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 val;
                        object o = GetColumnValueAtRow(source, rowNum);
                        if (Convert.IsDBNull(o))
                                val = this.NullText;
                        else
                                val = (string)o;
                        Rectangle rect = bounds;
                        g.FillRectangle(backBrush,rect);
                        rect.Offset(0, 2);
                        rect.Height -= 2;
                        g.DrawString(val,
this.DataGridTableStyle.DataGrid.Font, foreBrush, rect);
                }

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

        }
 

-- 
CJ


Relevant Pages

  • Re: DataGridView custom cell - losing first character on edit
    ... The edit functionality is in RichTextBoxEditingControl which is derived from ... derived from UserControl and has a RichTextBox embedded in its form. ... just as the DataGridView is entering edit mode for the cell. ... the editor control collects the data that is ...
    (microsoft.public.dotnet.framework.windowsforms)
  • DataGridView custom cell - losing first character on edit
    ... I've created a RichTextBox DataGridView cell but the first character entered ... the editor control collects the data that is ... this control is lost. ...
    (microsoft.public.dotnet.framework.windowsforms)
  • Re: Custom controls in datagrid
    ... > clicks the cell and the richtextbox gets focus, but the first character ... > before cell, the commit event is not fired. ... > added bottom row without having to click on it first? ...
    (microsoft.public.dotnet.framework.windowsforms.controls)
  • Re: Unusual paint situation
    ... > I have a third party grid control that does not support rich text as a ... cell type. ... Then in the paint event of the grid I would call the ... Maybe you can make the RichTextBox a child window of the grid, ...
    (microsoft.public.dotnet.general)
  • Re: problem with RichTextBox control
    ... Thanks Bill, that settles it: I'll give it a miss (the whole idea was to ... >> the table cell to span multiple rows. ... if I have an app that uses controls based on riched32.dll ... >> Why is the RichTextBox control so buggy? ...
    (microsoft.public.dotnet.framework.windowsforms)

Loading