How to Cancel BindingSource.PositionChanged Event?

T

Tomasz J

Hello Developers,



What I am trying to accomplish may seem trivial: simple data entry form with
DataRowView, BindingNavigator and several bound TextBoxes, DataRowView in
read-only mode.



When the user modifies data through one of the TextBoxes and then attempts
to change the current record he should be asked whether he wants to save
changes, cancel changes or abort.



And here is the problem: I found easy, consistent way of aborting the
attempt to move to another record. Technically speaking, I need a way to
cancel BindingSource.PositionChanged event, regardless of the original event
source, that is, regardless of whether user tries to reposition using
BindingNavigator or DataRowView.



Setting BindingSource.Position to the previous value inside the
BindingSource.PositionChanged event handler partially works - but only when
position is changed using BindingNavigator. When DataRowView is used, row
selected in DataRowView still changes, and selection no longer matches
BindingSource.Position, as well as row number displayed in BindingNavigator.



I also must be able to cancel PositionChanged in case user chooses to save,
but this operation fails.



Please advise. There must be some common way of implementing such typical
scenario.



Thank you.



Tomasz J
 
W

WenYuan Wang [MSFT]

Hello Tomasz,

According to your description, what you need to cancel the
BingdingSource.PositionChanged Event. Please correct me if I misunderstood
anything here.
(I assume what you talked about is DataGridView, because I cannot found the
DataRowView component in VS 2005. If I'm missing something here, please let
me know.)

If this is the case, I'm afraid to say there is no easy way to achieve your
requirement.

My suggestion is that you may disable the DataGridView. Thereby, the end
user cannot change the position of underling BindingSource.

Another way, we have to add a variable (currentPosition) which stored the
current position. If we need to cancel the positionChange operation, we can
change the BindingSource.Position propery back to that variable
(currentPosition) in BindingSource.PositionChanged event.

Hope this helps. Please let me know if you have any more concern. I'm glad
to assist you.

Have a great day.
Best regards,

Wen Yuan
Microsoft Online Community Support
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
T

Tomasz J

Hello WenYuan,

That is precisely what I try to do. I store the previous position and try to
restore it inside BindingSource.PositionChanged event handler. The problem
is that this approach does not work if the position change is initiated by
the DataGridView. BindingSource.Position property accepts new value, bound
BindingNavigator shows the correct (previous) record, but the DataGridView
current record does not move back to the previous position. So far I found
no way of correcting this problem.

Please advise.

Tomasz J


Sample code:

int _position = -1;

private void bindingSource1_PositionChanged(object sender, EventArgs e)
{
DataRowView previous = _position != -1 ?
(DataRowView)bindingSource1[_position] : null;
int current = bindingSource1.Position;

if (previous != null && current != _position && previous.Row.RowState !=
DataRowState.Unchanged) {
bindingSource1.Position = _position;
MessageBox.Show("save first!");
} else {
_position = current;
}
}
 
W

WenYuan Wang [MSFT]

Hello Tomaxz,
Thanks for your reply.

I have reproduced this issue. The issu is that: After we set the position
of BindingSource back to the previous value, the current row of
DataGridView doesn't move back to the correct record.

At first, I refresh the bindingSource.CurrentManger to force a repopulation
of the data-bound list.
if (previous != null && current != _position && previous.Row.RowState !=
DataRowState.Unchanged)
{
bindingSource1.Position = _position;
MessageBox.Show("save first!");
this.bindingSource1.CurrencyManager.Refresh();

}

This way could set the current row of DataGridView back to the previous
row. But, the "selected record symbol" still be displayed at the wrong
position. It seems like DataGridView repaint issue.

I spend about three hours to drill into the issue. The symbol is re-drawn
after bindingSource_PositionChanged event but its position is storned in
memory. And we can not change it when handel PositionChanged event.

Now, the workaround is that we add another flag (bool
_needBindSourceRefresh) to check if we need to refresh DataGridView in
SelectionChanged event.

bool _needBindSourceRefresh = false;
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (_needBindSourceRefresh)
{
_needBindSourceRefresh = false;
bindingSource1.CurrencyManager.Refresh();
}
}
private void bindingSource1_CurrentChanged(object sender, EventArgs e)
{
DataRowView previous = _position != -1 ?
(DataRowView)bindingSource1[_position] : null;
int current = bindingSource1.Position;

if (previous != null && current != _position &&
previous.Row.RowState != DataRowState.Unchanged)
{
bindingSource1.Position = _position;
MessageBox.Show("save first!");
_needBindSourceRefresh = true;
}
else
{
_position = current;
}

}


Hope this helps. Please try the above method and let me know if this method
works for you. I'm glad to assist you.

Have a great day,
Best regards,

Wen Yuan
Microsoft Online Community Support
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
T

Tomasz J

Hello WenYuan,

Thank you for all your help. I would not have figured this out on my own.

There was one more case I had to handle: user modifies record, but instead
of saving it, attempts to add a new one. But I think I found a satisfactory
solution.

I would probably either register a bug or feature request. For any reason it
is very difficult to implement such simple and typical scenarios using "out
of the box" components. With .Net it is even more difficult than it used to
be with old ADO, since neither PositionChanged nor ListChanged can be simply
cancelled.

Thank you.

Tomasz J
 
W

WenYuan Wang [MSFT]

You are welcome, Tomasz.
The pleasure is all mine.

It seems the issue has been resolved so far. Am I missing something here?
If you face any further issue, please feel free to update here again. We
are glad to assist you.

Have a great day,
Best regards,

Wen Yuan
Microsoft Online Community Support
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
W

WenYuan Wang [MSFT]

Hello Tomasz,
Thanks for your feedback.

According to the description from website, Product team reproduced this
issue. But the bug issue may not be fixed very soon. You can continue to
vote for this item if it is causing issues.

Please feel free to update here again if you have any more concern. We are
glad to assist you.

Have a great day,
Best regards,

Wen Yuan
Microsoft Online Community Support
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top