This is a migrated thread and some comments may be shown as answers.

How do I put a cell into edit mode automatically?

5 Answers 234 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Adam
Top achievements
Rank 1
Adam asked on 27 Jan 2012, 12:16 AM
quick background:
I notice that when a user tries to add a new row to a gridview, the row isn't bound to the data type until after the row is validated. This is problematic because I want to 'pre-populate' some of the fields based on what they enter in the first cell. If it was bound, it'd be simple as all I'd have to do is set the bound variable and the table would automatically populate...this doesn't appear feasible...

so I think I have, what I believe to be a work around...basically on a cell validation, I check to see if the row index == -1, if so then I cancel the edit and create a new CashReceivable object and add that to the bound list...the theory being that I'm esentially cancelling the edit and instead of adding the object via the gridview, I add it via the bound list...based on the code below, this works...

So what's my problem?
After this executes, the row gets added to the gridview just fine, the cell that I want to be selected is, however when I start typing to try the trustDGV.BeginEdit() (*note* I didn't include it in the code snipet below since it wasn't working, but I would assume I need to call this to put the cell into edit immediately mode) nothing happens...I am wanting it so as soon as this row gets added the second column goes directly into edit mode...What am I doing wrong?  *note* when I debugged it, I noticed that the currentCell rowIndex was still set to -1, even though I am speicifically setting the current row and column....it would appear as though currentCell is never being updated properly and I might need to do it during another event, but for the life of me, I dont see which event I could do it under...
 
        public ReceiptSplitWizard(String receiptNumber)
        {
            InitializeComponent();
 
            trustReceivables = new BindingList<CashReceivable>();
            trustDGV.DataSource = trustReceivables;
             
            trustDGV.CellValidated += new CellValidatedEventHandler(trustDGV_CellValidated);
            trustDGV.RowsChanged += new GridViewCollectionChangedEventHandler(trustDGV_RowsChanged);
 
             ... foreach loop here to add pre-existing receivables to the binding list to pre-populate it ...
}
 
        void trustDGV_CellValidated(object sender, CellValidatedEventArgs e)
        {
            if (e.RowIndex == -1)
            {
                if (e.Column.UniqueName.Equals("trustTargetInvoiceNumberDGVTBC"))
                {
                    CashReceivable receivable = CashReceivable.Clone(originalReceivable);
                    receivable.TXSet = null;
                    receivable.BillInvoiceNo = (String)e.Value;
                    receivable.CheckAmount = null;
                    receivable.BusinessFunction = GetBusinessFunction(receivable.BillInvoiceNo);
                    trustReceivables.Add(receivable);
                    trustDGV.MasterView.TableAddNewRow.CancelAddNewRow();
                    trustDGV.CurrentRow = trustDGV.Rows[trustDGV.Rows.Count - 1];
                    trustDGV.CurrentColumn = trustDGV.Columns[1];
                }
            }
     }
 
void trustDGV_RowsChanged(object sender, GridViewCollectionChangedEventArgs e)
        {
            GridViewDataRowInfo row = (GridViewDataRowInfo)e.NewItems[0];
 
            CashReceivable receivable = (CashReceivable)row.DataBoundItem;
 
            // if it's been distributed, then gray it out and set it readonly
            if (receivable.TXSet != null)
            {
                foreach (GridViewCellInfo cell in e.GridViewTemplate.Rows[e.NewStartingIndex].Cells)
                {
                    cell.Style.Font = new Font("Segoe UI", 8.25F, FontStyle.Italic);
                    cell.Style.ForeColor = Color.SlateGray;
                    cell.ReadOnly = true;
                }
            }
        }

5 Answers, 1 is accepted

Sort by
0
Accepted
Jack
Telerik team
answered on 31 Jan 2012, 10:45 AM
Hello Adam,

Thank you for contacting us.

You can initialize the new row in RadGridView by handling the DefaultValuesNeeded event. This event fires after clicking the "add new row" link and before entering edit mode. Consider the sample below:
void radGridView1_DefaultValuesNeeded(object sender, GridViewRowEventArgs e)
{
    e.Row.Cells["BillInvoiceNo"].Value = 10;
    //...
}

However, if you still want to add the row before finishing the validation, you can set the AddNewBoundRowBeforeEdit property to true:
this.radGridView1.MasterTemplate.AddNewBoundRowBeforeEdit = true;

In this case a new bound row will be created at the moment when clicking the "add new row" link.

I noted that you are setting the Style property in your code. You can improve the performance of your application by handling the CellFormatting event and setting CellElement properties directly. Please consider also that the Font object is a limited system resource. Creating a new Font instance every time when setting the Font property is not recommended. Instead, you can use the same Font instance for all cells. I modified your code the following way:
Font font = new Font("Segoe UI", 8.25F, FontStyle.Italic);
 
void radGridView1_CellFormatting(object sender, CellFormattingEventArgs e)
{
    if (e.CellElement is GridDataCellElement)
    {
        CashReceivable receivable = e.Row.DataBoundItem as CashReceivable;
 
        // if it's been distributed, then gray it out and set it readonly
        if (receivable != null && receivable.TXSet != null)
        {
            e.CellElement.Font = font;
            e.CellElement.ForeColor = Color.SlateGray;
            e.CellElement.ReadOnly = true;
        }
        else
        {
            e.CellElement.ResetValue(LightVisualElement.FontProperty, ValueResetFlags.Local);
            e.CellElement.ResetValue(LightVisualElement.ForeColorProperty, ValueResetFlags.Local);
            e.CellElement.ReadOnly = false;
        }
    }
}

I hope this helps. If you have further questions, do not hesitate to write back.

Regards,
Jack
the Telerik team

SP1 of Q3’11 of RadControls for WinForms is available for download (see what's new).

0
Adam
Top achievements
Rank 1
answered on 31 Jan 2012, 09:00 PM
Thanks, didn't realize I was doing that with the font, your suggestion is much cleaner...just an FYI, there is no ReadOnly on the cellelement...but there is the Enabled which I guess is the same thing, it works and looks nice and clean so I'm happy...

I am, however, still running into issues impelemnting your other suggestion...basically I did both things, added the MasterTemplate.AddNewBoundRowBeforeEdit and added .DefaultValuesNeeded event handler...it's not working as expected...The idea is this...the user is splitting receipts to pay for multiple invoices. As such, the receipts share pretty much all the same information with the exception of a few fields (which is what this grid view is trying to allow them to change). So I coded it up to add a new bound item, then when the defaultValuesNeeded gets fired, I grab that DataBoundItem and set all of the values to what the original ones are...In testing, I click on the new row, the default gets called and the receipt is updated properly...I manually type a new value into the cell and hit tab...at this point the cellvalidated event gets fired...when I grab the databound item during that event, it doesn't have any of the values that I set during the defaultValuesNeeded event....

here is the code, I put comments in to describe a few things...

public NewReceiptSplitWizard(String receiptNumber)
 {
        InitializeComponent();
 
        totalOtherSplits = totalTrustSplits = totalAvailable = 0;
             
        trustReceivables = new BindingList<CashReceivable>();
        otherReceivables = new BindingList<CashReceivable>();
 
        trustDGV.DataSource = trustReceivables;
        otherDGV.DataSource = otherReceivables;
 
        trustDGV.MasterTemplate.AddNewBoundRowBeforeEdit = true;
        otherDGV.MasterTemplate.AddNewBoundRowBeforeEdit = true;
 
        trustDGV.DefaultValuesNeeded += new GridViewRowEventHandler(dgv_DefaultValuesNeeded);
        trustDGV.CellValidated += new CellValidatedEventHandler(dgv_CellValidated);
        trustDGV.CellFormatting +=new CellFormattingEventHandler(dgv_CellFormatting);
        trustDGV.UserDeletingRow += new GridViewRowCancelEventHandler(dgv_UserDeletingRow);
 
        otherDGV.DefaultValuesNeeded += new GridViewRowEventHandler(dgv_DefaultValuesNeeded);
        otherDGV.CellValidated += new CellValidatedEventHandler(dgv_CellValidated);
        otherDGV.CellFormatting += new CellFormattingEventHandler(dgv_CellFormatting);
        otherDGV.UserDeletingRow += new GridViewRowCancelEventHandler(dgv_UserDeletingRow);
...
}
 
void dgv_DefaultValuesNeeded(object sender, GridViewRowEventArgs e)
 {
        CashReceivable receivable = e.Row.DataBoundItem as CashReceivable;
        receivable = originalReceivable.Clone();
        receivable.GenerateReceiptNumber();
        receivable.BillInvoiceNo = null;
        receivable.BusinessFunction = null;
        receivable.CheckAmount = null;
        receivable.OriginalTeller = User.userName;
        receivable.DtMod = DateTime.Today;
        receivable.WarrantCode = null;
        receivable.ApplicantName = null;
        receivable.Cmmnt = null;
        receivable.TrustNonTrust = (IsTrustDGV(sender)) ? CashConstants.TRUST : CashConstants.NON_TRUST;
             
// at this point the receivable is all setup and ready for them to enter in the new values that I have nulled out...
        }
 
void dgv_CellValidated(object sender, CellValidatedEventArgs e)
{
    bool isTrust = IsTrustDGV(sender);
 
    CashReceivable receivable = e.Row.DataBoundItem as CashReceivable;
 
// at this point, receivable is blank, has NONE of the values that were defined above
 
    ... some code to set other info on the receivable
}

0
Adam
Top achievements
Rank 1
answered on 31 Jan 2012, 09:09 PM
I should mention one other thing...the trustDGV and otherDGV radGridViews only display 3 columns which correspond to 3 of the 25 possible fields in a receivable...so trying to do the approach you showed (e.Row.Cells["BillInvoiceNo"].Value = 10;) wont work since there isn't a 1:1 correlation of cells to receivable fields...

long story short is that updaing the data bound item during DefaultValuesNeeded doesn't seem to actually work...

If there is another event I should be intercepting to set the databounditem values, let me know...I looked at RowsChanging, UserAddingRow, etc...but seems all of those fire after the CellValidated event and thus aren't set properly...

Worse case scenario is that I could set this info during the cell validated event, but that could be a little more ugly...

Hope this makes since, if not, let me know...



0
Adam
Top achievements
Rank 1
answered on 01 Feb 2012, 05:33 PM
disregard this, got it working...CLone was changing the reference thus breaking the binding. Thanks again for your help!
0
Jack
Telerik team
answered on 02 Feb 2012, 12:56 PM
Hi Adam, I am glad to hear that you have found what was wrong. If you have any further questions, I will be glad to help.
 
Greetings,
Jack
the Telerik team

SP1 of Q3’11 of RadControls for WinForms is available for download (see what's new).

Tags
GridView
Asked by
Adam
Top achievements
Rank 1
Answers by
Jack
Telerik team
Adam
Top achievements
Rank 1
Share this question
or