DataGridView:编辑时更改编辑控件大小

时间:2009-03-26 15:37:18

标签: c# datagridview edit

DataGridView 中的

我希望在编辑单元格时根据字符串长度扩展单元格大小。 Excel也是如此。

DataGridView 中,进入编辑模式时, DataGridViewTextBoxEditingControl 将被放置在单元格位置。我试图改变这个控件的边界/大小,但结果只是我所需大小的短暂闪烁。它直接覆盖了原始的截断方式。

有关如何使其发挥作用的任何想法?

谢谢,

蒂莫

7 个答案:

答案 0 :(得分:3)

这个问题很老了,但希望我的回答可以帮助有人继续前进。我遇到了同样的问题,并且能够使用类似于以下的过程使列宽在用户输入时动态更新,以确保文本适合列。

使用的事件:

  • CellBeginEdit
  • CellEndEdit
  • EditingControlShowing
  • TextBoxKeyPressEvent(即KeyPress

注意:以下代码假定AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells

// ---------------------------------------------------------------------------

private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
    // Copies the original column width because switching to DataGridViewAutoSizeColumnMode.None
    // will automatically make the column a default width.
    int origColumnWidth = dataGridView1.Columns[e.ColumnIndex].Width;

    dataGridView1.Columns[e.ColumnIndex].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;

    // Reverts back to the original width.
    dataGridView1.Columns[e.ColumnIndex].Width = origColumnWidth;
}

// ---------------------------------------------------------------------------

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    dataGridView1.Columns[e.ColumnIndex].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}

// ---------------------------------------------------------------------------

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    if (e.Control is TextBox)
    {
        var tbox = (e.Control as TextBox);

        // De-register the event FIRST so as to avoid multiple assignments (necessary to do this or the event
        // will be called +1 more time each time it's called).
        tbox.KeyPress -= TextBoxKeyPressEvent;
        tbox.KeyPress += TextBoxKeyPressEvent;
    }
}

// ---------------------------------------------------------------------------

private void TextBoxKeyPressEvent(object sender, KeyPressEventArgs e)
{
    // Gets the text prior to the new character being added.  Appending an arbitrary "0" to the value
    // to account for the missing character when determining appropriate measurements.
    string prevText = dataGridView1.CurrentCell.EditedFormattedValue.ToString() + "0";

    Graphics editControlGraphics = dataGridView1.EditingControl.CreateGraphics();

    // Gets the length of the current text value.
    SizeF stringSize = editControlGraphics.MeasureString(prevText, dataGridView1.EditingControl.Font);

    int widthForString = (int)Math.Round(stringSize.Width, 0);

    // Makes the column width big enough if it's not already.
    if (dataGridView1.CurrentCell.OwningColumn.Width < widthForString)
    {
        dataGridView1.CurrentCell.OwningColumn.Width = widthForString;
    }
}

编辑:更新TextBoxKeyPressEvent逻辑以考虑退格:

private void TextBoxKeyPressEvent(object sender, KeyPressEventArgs e)
        {
            string prevText;
            bool wasBackspaced = false;

            // The following logic will either add or remove a character to/from the text string depending if the user typed
            // an additional character or pressed the Backspace key.  At the end of the day, the cell will (at least) be
            // sized to the configured minimum column width or the largest row width in the column because we're using 
            // AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells.
            if (e.KeyChar == Convert.ToChar(Keys.Back))
            {
                prevText = dataGridView1.CurrentCell.EditedFormattedValue.ToString();

                if (prevText.Length == 0)
                {
                    // Don't try to make it any smaller...
                    return;
                }

                // Remove an arbitrary character for determining appropriate measurements.
                prevText = prevText.Remove(prevText.Length - 1);
                wasBackspaced = true;
            }
            else
            {
                // Gets the text prior to the new character being added.  Appending an arbitrary "0" to the value
                // to account for the missing character when determining appropriate measurements.
                prevText = dataGridView1.CurrentCell.EditedFormattedValue.ToString() + "0";
            }

            Graphics editControlGraphics = dataGridView1.EditingControl.CreateGraphics();

            // Gets the length of the current text value.
            SizeF stringSize = editControlGraphics.MeasureString(prevText, dataGridView1.EditingControl.Font);

            int widthForString = (int)Math.Round(stringSize.Width, 0);

            // Makes the column width big, or small, enough if it's not already.
            if (dataGridView1.CurrentCell.OwningColumn.Width < widthForString ||  // 1. Applies when adding text
                (dataGridView1.CurrentCell.OwningColumn.Width > widthForString &&          // ---
                 dataGridView1.CurrentCell.OwningColumn.MinimumWidth < widthForString &&   // 2. Applies when backspacing
                 wasBackspaced))                                                           // ---
            {
                dataGridView1.CurrentCell.OwningColumn.Width = widthForString;
            }
        }

答案 1 :(得分:2)

您需要首先覆盖DataGridViewCell.PositionEditingPanel Method。您需要重新定义自己的列类型和您自己的单元格类型才能访问此方法。

以下是一个如何操作的示例,它将编辑面板(拥有编辑控件的那个)的大小乘以2:

dataGridView1.AutoGenerateColumns = false; // disable columns auto generation

... add all columns

// add your special column
col = new MyColumn();
col.DataPropertyName = "Text"; // bind with the corresponding property
dataGridView1.Columns.Add(col); // add the custom column

... add other columns

public class MyCell : DataGridViewTextBoxCell
{
    public override Rectangle PositionEditingPanel(Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow)
    {
        cellBounds.Width *= 2;
        cellClip.Width = cellBounds.Width;
        return base.PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow);
    }
}

public class MyColumn : DataGridViewTextBoxColumn
{
    public MyColumn()
    {
        CellTemplate = new MyCell();
    }
}

答案 2 :(得分:0)

这对我有用:

启用表单的KeyPreview属性,并将表单的KeyPress事件的正文更改为:

private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
            if (e.KeyChar!='\b')   //discard backspace
            {
              dataGridView1.Columns[0].Width += 5;  //the column's index or name

            }
            else
            {
                dataGridView1.Columns[0].Width -= 5;  //for backspase pressing
            }
}

您可以使用e.KeyChar;

限制按下的键

答案 3 :(得分:0)

我找到了一些解决方案

一个使用MeasureString和一个datagridview,另一个创建另一个datagridview,以便在单元格具有该内容时确定单元格的正确宽度。另一个(我的最新版本)使用一个datagridview管理它并添加和删除一行。

这是使用第二个datagridview

的那个

在表格上绘制数据网格视图我已经给出了两列无数据。

代码将创建第二个datagridview,其中两列没有数据。

当然,提问者遇到的问题是没有编辑自动自动调整,它不清楚设置列的宽度。此解决方案创建另一个datagridview(称为DGVb),这个未添加到表单中。它将数据写入DGVb中的单元格,查看单元格所占的宽度,并使用该图形作为将单元格设置为正确DGV的图形。

Vine所涉及的另一个问题是,如果将单元格设置为自动调整大小,则无法以编程方式设置列的宽度,因此可以在触发cellbeginedit事件时启用代码,以设置自动调整大小没有,并在触发cellendedit时重新启用它,另一件事是因为设置为none可能会立即改变列大小,例如自动调整大小的column1可能是73,然后当你关闭自动调整大小时它会变为100,所以你可以在自动调整大小之前存储大小,然后将自动调整大小设置为无,并将大小设置为它是什么,这样就保留了不必要的尺寸变化这就是在这里所做的事情,如Vine所述。

此代码扩展和缩小列,并且没有后退删除,前向删除或箭头键的弱点,但在写作时,藤蔓的答案与这些键有一些弱点。我使用TextChanged来避免这些问题。 (与keydown e.t.c相反)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace datagridviewexpandcelldynamically_with_second_dgv
{
    public partial class Form1 : Form
    {
        DataGridView dgvtest = new DataGridView();
        //  DataGridView dgvtest;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

                dataGridView1.AllowUserToAddRows = false;
                dgvtest.AllowUserToAddRows = false;

                dataGridView1.CellBeginEdit += (object ssender, DataGridViewCellCancelEventArgs ee) =>
                {
                    //keep column width as it is for now but just change autosize to none so will be able to manually increase it
                    int origColumnWidth = dataGridView1.Columns[ee.ColumnIndex].Width;
                    dataGridView1.Columns[ee.ColumnIndex].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
                    dataGridView1.Columns[ee.ColumnIndex].Width = origColumnWidth;
                };

                dataGridView1.CellEndEdit += (object sssender, DataGridViewCellEventArgs eee) =>
                {
                    dataGridView1.Columns[eee.ColumnIndex].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                };

                dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
                dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

                dgvtest.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
                dgvtest.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;


                dgvtest.Columns.Add("Column1", "Column1");
                dgvtest.Columns.Add("Column2", "Column2");

                dgvtest.Rows.Add(1);
                dataGridView1.Rows.Add(1);

                /*
                Form newfrm = new Form();
                newfrm.Show();
                newfrm.Controls.Add(dgvtest);
                dgvtest.Show();
                */

                //dgvtest.Rows[0].Cells[0].Value = "abc";


        }



        private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {

            if (e.Control is TextBox)
            {
                var tbox = (e.Control as TextBox);

                // De-register the event FIRST so as to avoid multiple assignments (necessary to do this or the event
                // will be called +1 more time each time it's called).

                tbox.TextChanged -= TextBoxChanged;
                tbox.TextChanged += TextBoxChanged;
                //not KeyDown 'cos the character has not appeared yet in the box. and one would have to check what it was as a parameter, and if it's a backdelete then go back one.. and also forward delete isn't coutned as a keydown.
                //not KeyUp 'cos while yeah the character has at least appeared, there's a delay so if you hold backdelete then only after releasing it will it trigger the procedure, and updating the width of the cell then is a bit late.
                //not KeyPress 'cos has issues of keyup. 

            }

        }


        private void TextBoxChanged(object sender, EventArgs e)
        {


            int colindex = dataGridView1.CurrentCell.ColumnIndex;


            int oldcolwidth = dataGridView1.CurrentCell.Size.Width;
            //string stredit=dataGridView1.CurrentCell.EditedFormattedValue.ToString();
            string stredit=dataGridView1.EditingControl.Text;
            dgvtest.Rows[0].Cells[0].Value = stredit;

            int newcolwidth = dgvtest.Rows[0].Cells[0].Size.Width;

            int headercellsize = dataGridView1.Columns[colindex].HeaderCell.Size.Width;

            // find biggest existing one
            int maxcellincol = headercellsize;

            int tempcelllength = 0;
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                if (dataGridView1.Rows[i].Cells[colindex].Value == null) dataGridView1.Rows[i].Cells[colindex].Value = "";

                //length of all others but not current.
                tempcelllength = dataGridView1.Rows[i].Cells[colindex].Size.Width;

                if (tempcelllength > maxcellincol) maxcellincol = tempcelllength;
            }



            int diffcol = newcolwidth - oldcolwidth;

            // new isn't an ideal name.. 'cos it's not made new yet.. and 'cos if it's smaller than the max one then we won't make it the new one.. but it will be the new one if it's bigger than the max.

            // txtdesc.Text = "";
            txtdesc.Text += "newcolwidth=" + newcolwidth + "\r\n";
            txtdesc.Text += "maxcellincol=" + maxcellincol + "\r\n";


            //if (newcolwidth < maxcellincol)  != even if = then fine.

            dataGridView1.Columns[colindex].Width = newcolwidth;
            dataGridView1.Width += diffcol;

        } 

    }


}

将文本扩展为正在输入的文本的想法是一个非常黑的...但看起来在视觉上比这个替代方案更好..这样做不那么棘手,但看起来不那么好,就是说,只是将单元格大小扩展到cellbeginedit,(因此设置为autosize为none,并将col宽度设置为某个大小,如= 50),并将其缩小回大小 - 自动调整大小 - 在cellendedit上)然后我想在cellendedit上增加datagridview width,因此它没有滚动条。但是随后datagridview col会大小跳跃并且使用起来并不好。

答案 4 :(得分:0)

我在其他答案中提到我有两个解决方案,一个是MeasureString解决方案(而不是第二个datagridview解决方案)

提及textbox1-5.text e.t.c.已被评论它只是为了调试。

这个,另一个解决方案,不仅仅是调整您正在编辑的列的大小,它还调整了datagridview的宽度和表单宽度的大小,但是如果你没有&#39,你可以很容易地评论它。 ; t想要那种行为。

我应该使用&#39;使用&#39;用于创建图形对象的关键字,但无论如何。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace datagridviewexpandcelldynamically
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {

            int origColumnWidth = dataGridView1.Columns[e.ColumnIndex].Width;

            dataGridView1.Columns[e.ColumnIndex].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;

            dataGridView1.Columns[e.ColumnIndex].Width = origColumnWidth;

            if (dataGridView1.CurrentCell == null) dataGridView1.CurrentCell.Value = "";


        }

        private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            dataGridView1.Columns[e.ColumnIndex].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        }

        private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {

            if (e.Control is TextBox)
            {
                var tbox = (e.Control as TextBox);

                // De-register the event FIRST so as to avoid multiple assignments (necessary to do this or the event
                // will be called +1 more time each time it's called).

                tbox.TextChanged -= TextBoxChanged;
                tbox.TextChanged += TextBoxChanged;

            }

        }

        private void TextBoxChanged(object sender, EventArgs e)
        {

            // try catch is helpful in a winforms program 'cos otherwise program might just stop.
            // http://stackoverflow.com/questions/1583351/silent-failures-in-c-seemingly-unhandled-exceptions-that-does-not-crash-the-pr

            try
            {
                int colindex = dataGridView1.CurrentCell.ColumnIndex;

                Graphics agraphics = this.CreateGraphics();

                SizeF headerTextSize = agraphics.MeasureString(dataGridView1.Columns[colindex].HeaderText, dataGridView1.EditingControl.Font);

                // sometimes it goes black and this link here says to use editing control http://stackoverflow.com/questions/3207777/datagridview-cell-turns-black-when-accessing-editedformattedvalue

                // string stredit=dataGridView1.CurrentCell.EditedFormattedValue.ToString();
                string stredit=myDataGridView.EditingControl.Text;
                SizeF curCellTextSize = agraphics.MeasureString(stredit, dataGridView1.EditingControl.Font);
                //SizeF curCellTextSize = agraphics.MeasureString(dataGridView1.CurrentCell.GetEditedFormattedValue.ToString(), dataGridView1.EditingControl.Font);
                int curCellTextSize_i = (int)Math.Round(curCellTextSize.Width, 0);

                int headerCellSize = dataGridView1.Columns[colindex].Width;

                textBox2.Text = headerTextSize.Width.ToString();
                textBox3.Text = headerCellSize.ToString();

                // find biggest existing one
                int maxcelltextincol = (int)Math.Round(headerTextSize.Width,0);
                // the max size, at least for the header, includes a bit of padding.. 
                maxcelltextincol += 20;
                int tempcelllength=0;
                for(int i=0; i<dataGridView1.Rows.Count;i++) {
                    if (dataGridView1.Rows[i].Cells[colindex].Value == null) dataGridView1.Rows[i].Cells[colindex].Value = "";

                    tempcelllength = (int)Math.Round(agraphics.MeasureString(dataGridView1.Rows[i].Cells[colindex].Value.ToString(), dataGridView1.EditingControl.Font).Width, 0);

                    if (tempcelllength > maxcelltextincol) maxcelltextincol = tempcelllength;       
                }


            //    textBox2.Text = "PRE curCellTextSize_i=" + curCellTextSize_i + " " + "dgvw=" + dataGridView1.Columns[colindex].Width.ToString() + " max=" + maxcelltextincol.ToString() +  " prevstringlength=";

                string txtinwhatiamediting = stredit;

                SizeF sizelengthoftxtinwhatiamediting = agraphics.MeasureString(txtinwhatiamediting, dataGridView1.Font); //intermediate
                int lengthoftxtinwhatiamediting=(int)Math.Round(sizelengthoftxtinwhatiamediting.Width,0);

                //if(lengthoftxtinwhatiamediting>maxcelltextincol) 
                int amountovermax = lengthoftxtinwhatiamediting - maxcelltextincol;    


                int oldcolwidth = dataGridView1.Columns[colindex].Width;
                if (amountovermax < 0) { dataGridView1.Columns[colindex].Width = maxcelltextincol; return; }


                dataGridView1.Columns[colindex].Width = maxcelltextincol + amountovermax;
                int newcolwidth = dataGridView1.Columns[colindex].Width;
                   //dataGridView1.Width += (int)Math.Round((double)amountovermax,0);
                dataGridView1.Width += newcolwidth - oldcolwidth;
                this.Width += newcolwidth - oldcolwidth;
                //   textBox2.Text = "curCellTextSize_i=" + curCellTextSize_i + " " + "dgvw=" + dataGridView1.Columns[colindex].Width.ToString() + " max=" + maxcellincol.ToString();

                if (curCellTextSize_i > maxcelltextincol) maxcelltextincol = curCellTextSize_i;

                  // textBox5.Text= "POST curCellTextSize_i=" + curCellTextSize_i + " " + "dgvw=" + dataGridView1.Columns[colindex].Width.ToString() + " max=" + maxcelltextincol.ToString() + "prevstring=" + prevString + " prevstringlength=" + prevtextsize + " diff=" + diff;
                 //  textBox5.Text = "POST curCellTextSize_i=" + curCellTextSize_i + " " + "dgvw=" + dataGridView1.Columns[colindex].Width.ToString() + " max=" + maxcelltextincol.ToString() + " diff=" + amountovermax;


            }
            catch (Exception ee) { MessageBox.Show(ee.ToString()); }                                
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                //dataGridView1.AllowUserToAddRows = false;
                dataGridView1.Font = new System.Drawing.Font("David", 30.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                dataGridView1.Rows.Add(1);

                dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
                dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;                

                Graphics g = this.CreateGraphics(); // should be in a using.

                Font fontA = new System.Drawing.Font("David", 30.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));

                SizeF headerSize = g.MeasureString(dataGridView1.Columns[0].HeaderText, fontA);

                int totalcolwidth = dataGridView1.RowHeadersWidth + 40; // about 40+70
                //MessageBox.Show(totalcolwidth.ToString());
                for (int i = 0; i < dataGridView1.Columns.Count; i++)
                    totalcolwidth += dataGridView1.Columns[i].Width;

              //  MessageBox.Show(totalcolwidth.ToString());
              //  MessageBox.Show(dataGridView1.Width.ToString());
                int diff = totalcolwidth - dataGridView1.Width;
                dataGridView1.Width = totalcolwidth;
              //  MessageBox.Show(dataGridView1.Width.ToString());
                this.Width += diff;

            }
            catch (Exception exc)
            {
                MessageBox.Show("exception ");
                MessageBox.Show(exc.ToString());
            }
        }


    }
}

答案 5 :(得分:0)

这个解决方案(我最新的)使用了与使用2个datagridviews的答案类似的技术,但它只用一个datagridview来管理它。

它的作用是将文本输入单元格时,它会创建一个新行,并将该文本输入该行内相应列的该行。然后它会看到新宽度应该是什么,并将列扩展到该宽度并删除该行。

这是对我所拥有的内容的编辑,它改进了它。因为事实证明我可以注释掉cellbeginedit和cellendedit方法。它还发现,虽然前一个很好,但稍微修改会导致黑色单元格的错误,这里提到了。只要我自动调整所有列,我就避免使用黑色单元格。 (那和我一样使用EditingControl.Text)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace dgveditresize
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

            //DGVprocs.dgv = dataGridView1;
            dataGridView1.AllowUserToAddRows = false;

            autoshrinkwholedgv();

            //DGVprocs.autoshrink_off_wholedgv__preservewidths(); not necessary
            dataGridView1.Rows.Add(5);
            //dataGridView1.CellBeginEdit += OnCellBeginEditExpandCol;

             dataGridView1.EditingControlShowing += DataGridView1_EditingControlShowing;

          //  MessageBox.Show(dataGridView1.Columns[1].Width.ToString());
        }


        private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {

           // MessageBox.Show(dataGridView1.Columns[1].Width.ToString());



            // http://stackoverflow.com/questions/37505883/how-can-i-dynamically-detect-the-characters-in-a-datagridview-cell-execute-co

            //if(DGVprocs.isshrinkon()==false) { MessageBox.Show("err ")}

            if (e.Control is TextBox)
            {
                var tbox = (e.Control as TextBox);

                // De-register the event FIRST so as to avoid multiple assignments (necessary to do this or the event
                // will be called +1 more time each time it's called).

                tbox.TextChanged -= A_Cell_TextChanged;
                tbox.TextChanged += A_Cell_TextChanged;
            }



        }

        private void A_Cell_TextChanged(object sender, EventArgs e)
        {

            dataGridView1.Rows.Add(1);

            //MessageBox.Show(dataGridView1.Rows.Count+" rows");

            int colindex = dataGridView1.CurrentCell.ColumnIndex;


            int oldcolwidth = dataGridView1.CurrentCell.Size.Width;
            //string stredit=dataGridView1.CurrentCell.EditedFormattedValue.ToString();
            string stredit = dataGridView1.EditingControl.Text;

            //dgvtest.Rows[0].Cells[0].Value = stredit;
            dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[dataGridView1.CurrentCell.ColumnIndex].Value = stredit;
            //MessageBox.Show(dataGridView1.Rows.Count + " rows");
            //int newcolwidth = dgvtest.Rows[0].Cells[0].Size.Width;

            //autoshrinkcurrentcol(); // WORSE   (1)  WW
            autoshrinkwholedgv(); //added BETTER (2)  XX
            int newcolwidth = dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[dataGridView1.CurrentCell.ColumnIndex].Size.Width;
            autoshrinkoff_wholedgv_preservewidths(); //added BETTER (3) YY
           // autoshrink_off_currentcol_preservewidth(); // WORSE (4)  ZZ
             /*               
             WAS ERROR WITH THIS ONE..
             IF YOU TYPE IN THE FIRST CELL THEN HIT DOWN ARROW TWICE
             THEN TYPE THEN IT GOES BLACK
             BUT PROBLEM RESOLVED  SINCE USING 2,3 RATHER THAN 1,4                    
              */
            // doing either  1,4  or 2,3
            // no comparison
            // 1,4 causes blackness.
            // 2,3 and it works
            // all of them is just same as 2,3 not surprising.
            // but funny that 1,4 causes blackness.


            //MessageBox.Show("removing row");

            if(dataGridView1.AllowUserToAddRows) { MessageBox.Show("programmer msg- issue in 'cell's textchanged method', allowusertoaddrows must be false otherwise an exception is thrown by the next line dataGridView1.Rows.RemoveAt(dataGridView1.Rows.Count - 1);"); Application.Exit(); }
                // requires user not add row set to true.
                dataGridView1.Rows.RemoveAt(dataGridView1.Rows.Count - 1);

            //MessageBox.Show(dataGridView1.Rows.Count + " rows");

            int headercellsize = dataGridView1.Columns[colindex].HeaderCell.Size.Width;

            // find biggest existing one
            int maxcellincol = headercellsize;

            int tempcelllength = 0;
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                if (dataGridView1.Rows[i].Cells[colindex].Value == null) dataGridView1.Rows[i].Cells[colindex].Value = "";

                //length of all others but not current.
                tempcelllength = dataGridView1.Rows[i].Cells[colindex].Size.Width;

                if (tempcelllength > maxcellincol) maxcellincol = tempcelllength;
            }



            int diffcol = newcolwidth - oldcolwidth;

            // new isn't an ideal name.. 'cos it's not made new yet.. and 'cos if it's smaller than the max one then we won't make it the new one.. but it will be the new one if it's bigger than the max.

             txtdesc.Text = "";
            txtdesc.Text += "newcolwidth=" + newcolwidth + "\r\n";
            txtdesc.Text += "maxcellincol=" + maxcellincol + "\r\n";


            //if (newcolwidth < maxcellincol)  != even if = then fine.

            // say we move that earlier
            //dataGridView1.Rows.RemoveAt(dataGridView1.Rows.Count - 1);

            //DGVprocs.autoshrinkoff_preservecurrentcolwidth();


            //if (dataGridView1.Columns[colindex].Width == newcolwidth)
            if (oldcolwidth == newcolwidth)
            txtwidthcomp.Text="old width is equal to cur width diff="+diffcol;
            else
                txtwidthcomp.Text="old width is not equal to cur width diff="+diffcol;

            //shrink should never be on while there's an editbox showing.
            //if (diffcol>0) if (DGVprocs.isshrinkon() == true) MessageBox.Show("shrink is on this may be why it's not resizing");
            // when turning autoshrink off a)it should be done after the editbox it will freeze the editbox to the size that it was. b)when it is done it should be done in a preservational way. getting all col sizes beforehand and turning shrink off and setting all cols to that size that they were 
            // DGVprocs.autoshrinkoff();
            // shrink has to be off for the current column.. doesn't matter about the rest of it.
            // if(diffcol>0) if(DGVprocs.isshrinkoncurrentcol()==true) MessageBox.Show("shrink is on(cur col) this may be why it's not resizing");



            dataGridView1.Columns[colindex].Width = newcolwidth;
            dataGridView1.Width += diffcol;


            // i think autoshrink while the editbox is showing is wrong.
            // you need to autoshrink it to size of editbox.
//            DGVprocs.autoshrink();


        }


        public void autoshrinkwholedgv()
        {

            dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

            return;
        }

        public void autoshrinkcurrentcol()
        {

            dataGridView1.Columns[getcurrentcol()].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

            //this may be optional.
            dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;

            // DGVprocs.dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

            return;
        }

        public int getcurrentcol()
        {
            if (dataGridView1.CurrentCell == null) { MessageBox.Show("Programmer msg - getcurrentcol() error, current cell not selected"); Application.Exit(); }
            if (dataGridView1.CurrentCell.Value == null) dataGridView1.CurrentCell.Value = "";

            return dataGridView1.CurrentCell.ColumnIndex;
        }

        public void autoshrink_off_currentcol_preservewidth()
        {
            int w =  dataGridView1.Columns[getcurrentcol()].Width;
            dataGridView1.Columns[getcurrentcol()].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
            dataGridView1.Columns[getcurrentcol()].Width = w;
        }

        public void autoshrinkoff_wholedgv_preservewidths()
        {
            // deal with the 73,100 bug.. whereby if you ave autoresize on immediately, then a DGV with Column1 Colum2, Column3 e.t.c. has width of 73. But then when turning autoresize off it goes to 100. 

            int[] colsizes = new int[dataGridView1.Columns.Count];

            for (int i = 0; i < dataGridView1.Columns.Count; i++)
                colsizes[i] = dataGridView1.Columns[i].Width;

            dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;

            for (int i = 0; i < dataGridView1.Columns.Count; i++)
                dataGridView1.Columns[i].Width = colsizes[i];


            return;
        }

    }


}

答案 6 :(得分:-1)

您希望在键入时调整单元格大小吗?或者,您是否希望在输入文本并输入命中后调整大小?第二种选择是最公平的。

让我知道。

由于

相关问题