EditableRootList and Undo problem

EditableRootList and Undo problem

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


Mahmud posted on Wednesday, June 06, 2007

LAst few days I have been struggling days and nights to implement EditableRootListBase. My scenario is:

(1) A gridview bound with an EditableRootList, _currencycs (CurrencyId, CurrencyName and ConversionRate)

(2) We disabled 'Add New' in grid, so user have to press 'New' button to add records in gridview. In the New button code we inserted a new record in gridview by - _currencycs.AddNew() . This adds and saves the new record in the editablerootlist collection. So, Eas does not undo the new entry.

(3) Now, the problem is regarding Undo. We have code in 'RowValidating' where we check whether CurrencyName is empty or CurrencyRate is 0. If the error condition is there, then we set Cancel=true. We have put the following code in Undo button -

gridMain.CancelEdit(<current row>)

If the 'Undo' is pressed when there is no error, then its OK - and undo works perfectly. But after the row has not been passed RowValidating, then error comes.

I would like to get a clear idea about how to Undo changes with EditableRootList when RowValidating in gridview is in effect. This is very urgent, because all of our dictionary tables will be edited this way.

 

 

 

 

RockfordLhotka replied on Thursday, June 07, 2007

Two things.

First, the whole idea of CSLA is to help you get all business logic out of the UI. That code you are writing in step 3 is putting business logic into the UI. I suggest you don't do that.

Second, what is the error?

Mahmud replied on Thursday, June 07, 2007

RowValidating is the only place that I know, where to write validation code for a specific row before saving for validity. Any other alternatives? Are you proposing AddBusinessRule? Then check for broken rules?

The error is: Operation did not succeed because the program cannot commit or quit a cell value change.

 

ajj3085 replied on Thursday, June 07, 2007

Yes, creating  a rule method, then using AddBusinessRule would be the best way to go.  Your BO would likely then accept the invalid value, but because the rule would be run (via the PropertyHasChanged method you call in the property setter), Save would thrown an exception.  The cell or row (depending on how the grid is configured) would show a red circle with a white ! mark in it.

HTH
Andy

Mahmud replied on Friday, June 08, 2007

I am still waiting to get a clear indication of how to handle Undo in gridview bound to an EditableRootList.  

ajj3085 replied on Friday, June 08, 2007

Undoing changes to all the items in the grid?  Or just to one item?  The former goes against what ERL is meant to do, which is commit each row as the user leaves it (thus accepting the changes).  I would think that pressing ESC should be enough to undo changes to a row, provided you haven't left the row yet.

Mahmud replied on Saturday, June 09, 2007

We have to remove the facility of AllowNew from the grid, according to our design team. Now, the undo for a new row is not working as expected (pressing Esc does not undo a new row). We are using EditableRootList, so every row is on its own - if you move from the row - its saving automatically.

Still unable to find a workable solution...

Mahmud replied on Saturday, June 09, 2007

I think, I should explain a little bit more - so that at least someone with clear understanding of CSLA and gridview can help me out.

(1) We have bound a gridview with a bindingsource bound to a EditableRootListBase - CurrencyList of Currency objects. The gridview has AllowUsersToAddRows set to False. So there is no New Record line in the gridview.

(2) We have a NEW button, here is the code -

if (!gridMain.IsCurrentRowDirty)

{

bsCurrency.AddNew();

gridMain.Focus();

gridMain.CurrentCell = gridMain.Rows[gridMain.RowCount - 1].Cells[1];

}

(3) We have an Undo button, here is the code -

atlMSLibrary.Currency lineobj = (atlMSLibrary.Currency)bsCurrency.Current;

if (lineobj.IsNew)

{

int lineindex = gridMain.CurrentRow.Index;

gridMain.DataSource = null;

bsCurrency.RemoveAt(lineindex);

_currencys.CancelNew(lineindex);

RefreshData();

gridMain.DataSource = bsCurrency;

}

else if (lineobj.IsDirty)

{

RefreshData();

}

(4) We validate every record in the gridview RowValidating event -

atlMSLibrary.Currency lineobj = (atlMSLibrary.Currency)(gridMain.Rows[e.RowIndex].DataBoundItem);

if (lineobj != null)

{

if (!_bNewRecord && lineobj.IsNew && lineobj.BrokenRulesCollection.Count == 0)

lineobj.CheckValidity();

if (lineobj.BrokenRulesCollection.Count > 0)

e.Cancel = true;

}

(5) CheckValidity calls Validation.CheckRules(). There is only one rule set in the business class - CurrencyName is required. So, when user tries to move from the new row and does not give CurrencyName, the RowValidating runs and ensures that the user cannot move from the error row.

Can anyone suggest whether this is the right way to proceed, or we have some erronious code...

 

Mahmud replied on Saturday, June 09, 2007

I think, I should explain a little bit more - so that at least someone with clear understanding of CSLA and gridview can help me out.

(1) We have bound a gridview with a bindingsource bound to a EditableRootListBase - CurrencyList of Currency objects. The gridview has AllowUsersToAddRows set to False. So there is no New Record line in the gridview.

(2) We have a NEW button, here is the code -

if (!gridMain.IsCurrentRowDirty)

{

bsCurrency.AddNew();

gridMain.Focus();

gridMain.CurrentCell = gridMain.Rows[gridMain.RowCount - 1].Cells[1];

}

(3) We have an Undo button, here is the code -

atlMSLibrary.Currency lineobj = (atlMSLibrary.Currency)bsCurrency.Current;

if (lineobj.IsNew)

{

int lineindex = gridMain.CurrentRow.Index;

gridMain.DataSource = null;

bsCurrency.RemoveAt(lineindex);

_currencys.CancelNew(lineindex);

RefreshData();

gridMain.DataSource = bsCurrency;

}

else if (lineobj.IsDirty)

{

RefreshData();

}

(4) We validate every record in the gridview RowValidating event -

atlMSLibrary.Currency lineobj = (atlMSLibrary.Currency)(gridMain.Rows[e.RowIndex].DataBoundItem);

if (lineobj != null)

{

if (!_bNewRecord && lineobj.IsNew && lineobj.BrokenRulesCollection.Count == 0)

lineobj.CheckValidity();

if (lineobj.BrokenRulesCollection.Count > 0)

e.Cancel = true;

}

(5) CheckValidity calls Validation.CheckRules(). There is only one rule set in the business class - CurrencyName is required. So, when user tries to move from the new row and does not give CurrencyName, the RowValidating runs and ensures that the user cannot move from the error row.

Can anyone suggest whether this is the right way to proceed, or we have some erronious code...

 

RockfordLhotka replied on Saturday, June 09, 2007

Mahmud:

We have to remove the facility of AllowNew from the grid, according to our design team. Now, the undo for a new row is not working as expected (pressing Esc does not undo a new row). We are using EditableRootList, so every row is on its own - if you move from the row - its saving automatically.

Still unable to find a workable solution...

I'm not entirely sure this is possible then. The grid isn't designed to do what you want, and you'll have to figure out how to trick the grid and/or data binding into doing this.

When you add the item to your list, it is added to the grid, but in a way such that the grid doesn't think it is new (because it came from an external source, not the grid). That's why ESC won't get rid of it.

Your only hope (I think) is to perhaps catch the ESC keypress in the grid (keyup handler or something) and force removal of the new item - assuming you can detect it is a new one in some way.

Copyright (c) Marimer LLC