CSLA-beginner DataBinding, EditCancel, DataGridView trouble.

CSLA-beginner DataBinding, EditCancel, DataGridView trouble.

Old forum URL: forums.lhotka.net/forums/t/2083.aspx


zap posted on Friday, January 05, 2007

      
    Please Help, somebody!
    
    Preq:
    CSLA 2.1.1
    WinForm
    Simple Parent Child (Order, OrderLines)
    OrderLines in DataGridView
    AllowAdd = true
    Using only DataBinding Undo (I don't impl Order.BeginEdit();)
    
    ProblemScenario:
    Adding frist row in grid (cre OrderLindes wh default values)
    Pressing ESC. Intending to remove the row.
    BusinessListBase.InsertItem is throwing an Error. Se ERROR below
    
    NoProblemScenarion:
    Adding first row completly
    Adding second row
    Pressing ESC. Intending to remove the second row.
    The Row is removed as expected.
    
    ERROR:
    When I Debug the code the dataBinding infrastructure try to create two new
    OrderLine objects
    And when the second is created the BusinessListBase.InsertItem throwing this error.
        
    BusinessListBase:
    protected override void InsertItem(int index, C item)
    {
        // when an object is inserted we assume it is
        // a new object and so the edit level when it was
        // added must be set
        item.EditLevelAdded = _editLevel;
        item.SetParent(this);
        base.InsertItem(index, item); <-- Err is thrown
    }
    
    StackTrace:
    System.InvalidOperationException was unhandled
  Message="Operation is not valid due to the current state of the object."
  Source="System.Windows.Forms"
  StackTrace:
       at System.Windows.Forms.DataGridView.DataGridViewDataConnection.ProcessListChanged(ListChangedEventArgs e)
       at System.Windows.Forms.DataGridView.DataGridViewDataConnection.currencyManager_ListChanged(Object sender, ListChangedEventArgs e)
       at System.Windows.Forms.CurrencyManager.OnListChanged(ListChangedEventArgs e)
       at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
       at System.Windows.Forms.BindingSource.OnListChanged(ListChangedEventArgs e)
       at System.Windows.Forms.BindingSource.InnerList_ListChanged(Object sender, ListChangedEventArgs e)
       at System.ComponentModel.BindingList`1.OnListChanged(ListChangedEventArgs e)
       at System.ComponentModel.BindingList`1.InsertItem(Int32 index, T item)
       at Csla.BusinessListBase`2.InsertItem(Int32 index, C item) in C:\Documents and Settings\Klas-Erik Bjuhr\Mina dokument\Visual Studio 2005\Projects\csla20cs\csla20cs\Csla\BusinessListBase.cs:line 369
       at System.Collections.ObjectModel.Collection`1.Add(T item)
       at Servex.Library.ServiceOrderLines.AddNewCore() in C:\Documents and Settings\Klas-Erik Bjuhr\Mina dokument\Visual Studio 2005\Projects\CslaTestProj\Servex\Servex.Library\ServiceOrderLines.cs:line 114
       at System.ComponentModel.BindingList`1.System.ComponentModel.IBindingList.AddNew()
       at System.Windows.Forms.BindingSource.AddNew()
       at System.Windows.Forms.CurrencyManager.AddNew()
       at System.Windows.Forms.DataGridView.DataGridViewDataConnection.AddNew()
       at System.Windows.Forms.DataGridView.DataGridViewDataConnection.OnNewRowNeeded()
       at System.Windows.Forms.DataGridView.OnRowEnter(DataGridViewCell& dataGridViewCell, Int32 columnIndex, Int32 rowIndex, Boolean canCreateNewRow, Boolean validationFailureOccurred)
       at System.Windows.Forms.DataGridView.SetCurrentCellAddressCore(Int32 columnIndex, Int32 rowIndex, Boolean setAnchorCellAddress, Boolean validateCurrentCell, Boolean throughMouseClick)
       at System.Windows.Forms.DataGridView.SetAndSelectCurrentCellAddress(Int32 columnIndex, Int32 rowIndex, Boolean setAnchorCellAddress, Boolean validateCurrentCell, Boolean throughMouseClick, Boolean clearSelection, Boolean forceCurrentCellSelection)
       at System.Windows.Forms.DataGridView.CancelEdit(Boolean endEdit)
       at System.Windows.Forms.DataGridView.ProcessEscapeKey(Keys keyData)
       at System.Windows.Forms.DataGridView.ProcessDataGridViewKey(KeyEventArgs e)
       at System.Windows.Forms.DataGridView.OnKeyDown(KeyEventArgs e)
       at System.Windows.Forms.Control.ProcessKeyEventArgs(Message& m)
       at System.Windows.Forms.DataGridView.ProcessKeyEventArgs(Message& m)
       at System.Windows.Forms.Control.ProcessKeyMessage(Message& m)
       at System.Windows.Forms.Control.WmKeyChar(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.DataGridView.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Servex.Program.Main() in C:\Documents and Settings\Klas-Erik Bjuhr\Mina dokument\Visual Studio 2005\Projects\CslaTestProj\Servex\Servex\Program.cs:line 17
       at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()

zap replied on Saturday, January 06, 2007

Just discover that when I put focus on the first row, thus create it, and after that,put focus on another ctrl, the row is removed, as expected. The problem only arise when I use the ESC-button to do the same thing (on the first row).

Can't be the only one with problem like this or?

What am I doing wrong?

zap replied on Saturday, January 06, 2007

... and if I don't rise the OnUnknownPropertyChanged()
        protected override void OnUnknownPropertyChanged()
        {
            //base.OnUnknownPropertyChanged();
        }
the Error disappear and the first row stays ( even if I press ESC) until I remove the focus.

When I use an DataTable as DataSource, the Grid behaves in the same way. So I suppose my problem has to do with the UnknownPropertyChanged event in some way..







ajj3085 replied on Monday, January 08, 2007

What grid are you using?

Also, how are you adding rows? Are you leaving it purely to the grid?  Are you calling Apply or Cancel edit on anything other than a BindingSource object?

zap replied on Monday, January 08, 2007

Thank's for your interest ajj !!!!

What grid are you using?/ MS DataGridView
...Are you leaving it purely to the grid? / Yes
Are you calling Apply or Cancel edit on anything other than a BindingSource object? /No

I have tried both to use "BindingSource" apporach and "the old" way i.e set the grid.DataSource = parentObj.childObects, with the same result.

/zap

JZuerlein replied on Wednesday, February 28, 2007

Zap....Did you find a solution to this problem?

I've got the same exact one.  It only occurs when you try to cancel adding a new row, and it's the first one in the collection.  When you do that, it calls AddNewCore twice.

Jeff

JZuerlein replied on Wednesday, February 28, 2007

I'm pretty sure this is a bug in the DataGridView control as referenced by....

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=197067

Has anyone found a work around to the problem?

Jeff

zap replied on Thursday, March 01, 2007

Hi Jeff! I have kind of leave this problem behind me ;)


But Yes, it looks like a bug in the DataGridView... to me to..

I have find no real work around, but if you don't call
base.OnUnknownPropertyChanged()
the problem "dissapere".

protected override void OnUnknownPropertyChanged()
{
// Just don't call it since there is trouble with it when
ESC and first row
// in grid.
// base.OnUnknownPropertyChanged();

}

I have also elaborate with things like below:

private void serviceOrderLinesDataGridView_KeyDown(object sender,
KeyEventArgs e)
{
//if (e.KeyCode == Keys.Escape)
//{
//
_serviceOrder.ServiceOrderLines.CancelNew(serviceOrderLinesBindingSource.Count-1);
// e.SuppressKeyPress = true;
// e.Handled = true;

//}

}

I can do some testing with the Infragistics grid an see how i behaves..





JZuerlein skrev:
>
> I'm pretty sure this is a bug in the DataGridView control as
> referenced by....
>
> https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=197067
>
> Has anyone found a work around to the problem?
>
> Jeff
>
>
>
>

zap replied on Friday, March 02, 2007

FYI

The Infragistics Grid 2006 Vol3 works as expected!

/zap

JZuerlein replied on Thursday, March 08, 2007

Thanks Zap.

I've confirmed with MS that this bug is the one I mentioned earlier.  There is no work around, and the hotfix has not been released to the public. 

ajj3085 replied on Friday, March 09, 2007

Can those experiencing this problem request the hotfix?  If so, how?

stephen.fung replied on Wednesday, June 27, 2007

Although this thread is fairly old, I thought I would add my findings in case they help anyone later:

- Pressing escape on a new row without any edits would throw that exception
- On a new row, making an edit causes another "NewRow" to show up beneath, which makes IsNewRow return false, but pressing escape will still cancel the addition of this row and remove it (causing that exception if it's the first row)
- If it's not a new row, then pressing escape will cancel the edit in the last cell you changed.

Some approaches posted here, the one posted by Mustafa Kamil helped but didn't address the problem when the new row had been partially edited.
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=301807&SiteID=1

The following code (in a subclass of DataGridView) seems to fix these problems for me while preserving the Escape key's expected semantics:

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Escape)
            {
                //See if the Escape key cancelled a "new row" (this doesn't seem to work with
                //checking IsNewRow)
                //If not, then process the escape key as normal
                ICancelAddNew bl2 = DataSource as ICancelAddNew;
                IBindingList bl = DataSource as IBindingList;

                //If we don't have a bindable/cancellable DataSource, then just process the escape key as normal
                if (bl != null && bl2 != null)
                {
                    //Try to cancel adding the new row
                    int oldCount = bl.Count;
                    bl2.CancelNew(CurrentCell.RowIndex);
                    if (bl.Count != oldCount)
                    {
                        //If it was a new row and was cancelled, then we're done,
                        //bypass the bug.
                        return true;
                    }
                    //If it wasn't a new row, then process as usual.
                }
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }


Tested on Windows Vista.

Copyright (c) Marimer LLC