473,388 Members | 1,376 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

Re: Linq-SQL canonical editable datagridview sample code

Marc,
>I don't know if there is an easier way, but how about:
Thank you very much. I have issue on implementing add row properly using
this.

User presses down arrow in last row in grid starting adding new row.
Then user changes its mind desiding that new row should not added and
presses up arrow.
DataGridView does not show this unfinished row anymore.

However entity remains in DataContext and is added to database on
SubmitChanges.
How to prevent this ghost entity addition ?

Andrus.
Jun 27 '08 #1
18 6014
Probably you'd need to implement ICancelAddNew, but taking a peek,
BindingList<Talready does this, calling RemoveItem correctly...
hmmm... I'll investigate...
Jun 27 '08 #2
I've looked at this with LINQ-to-SQL, and I cannot reproduce the
issue; if I add and remove a row (in any combination of immediate and
delayed cancel), then no change is applied to the database.

So: are you using LINQ-to-SQL, or are you using DbLinq? If the latter,
then I suspect it has "issues" noticing this trivial change (trivial
meant in the literal sense - not intended to be patronising).

You might be able to write the list to track insertions itself, but
this should be the job of the data-context. Of course, if this
actually is LINQ-to-SQL, please let me know and I'll retry...

Marc
Jun 27 '08 #3
Marc,
>Probably you'd need to implement ICancelAddNew, but taking a peek,
BindingList<Talready does this, calling RemoveItem correctly...
I observed the following:

1. Pressing down arrow in last line of DataGridView calls AddNewCore() which
adds new entity to
DataContext.

2. Pressing Up Arrow doest *not* call RemoveItem. So added fake entity will
me saved on SubmitChanges().

I'm wondering how Linq-SQL performs this correctly since RemoveItem() is not
called.

I'm using DbLinq but this should not depend on Linq provider.

Andrus.
Jun 27 '08 #4
Marc,
I've looked at this with LINQ-to-SQL, and I cannot reproduce the
issue; if I add and remove a row (in any combination of immediate and
delayed cancel), then no change is applied to the database.
I'm planning to fix this in the following way:

1. AddNewCode() assigns new entity to property only, will not add to
DataContext
2. Override ICancelAddNew EndNew() method and add new entity to DataContext
in this method.

Will this work OK ?

Andrus.
Jun 27 '08 #5
Probably - but you can't *fully* verify the cancel conditions (the
index etc) since they aren't available as protected... I added
Console.WriteLine to RemoveItem, and it seemed to be working fine...

Marc
Jun 27 '08 #6
Marc,
Probably - but you can't *fully* verify the cancel conditions (the
index etc) since they aren't available as protected... I added
Console.WriteLine to RemoveItem, and it seemed to be working fine...
I found that this occurs only when I move up-down in my
CustomDataGridViewComBobox column.

Down arrow in this column invokes AddNewCore().
Up arrow does *not* invoke RemoveItem.
Pressing down arrow again causes InvalidOperationException in
base.AddNewCore()

It seems that my combobox column class blocks bindinglist RemoveItem call.
I checked my class overridden methods and it seems that I'm calling base
methods in most cases.
Which combobox columns method calls bindinglist RemoveItem() ?
I implemented combobox column using MSDN sample code.

Any idea how to debug / resolve this issue? Exception which I got is below.

Andrus.

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.DataGridViewData Connection.ProcessListChanged(ListChangedEventArgs
e)
at
System.Windows.Forms.DataGridView.DataGridViewData Connection.currencyManager_ListChanged(Object
sender, ListChangedEventArgs e)
at
System.Windows.Forms.CurrencyManager.OnListChanged (ListChangedEventArgs e)
at System.Windows.Forms.CurrencyManager.List_ListChan ged(Object
sender, ListChangedEventArgs e)
at
System.ComponentModel.BindingList`1.OnListChanged( ListChangedEventArgs e)
at System.ComponentModel.BindingList`1.InsertItem(Int 32 index, T
item)
at System.Collections.ObjectModel.Collection`1.Add(T item)
at System.ComponentModel.BindingList`1.AddNewCore()
at MyAppl.TableList`1.AddNewCore() in I:\MyAppl\TableList.cs:line 92
at
System.ComponentModel.BindingList`1.System.Compone ntModel.IBindingList.AddNew()
at System.Windows.Forms.CurrencyManager.AddNew()
at
System.Windows.Forms.DataGridView.DataGridViewData Connection.AddNew()
at
System.Windows.Forms.DataGridView.DataGridViewData Connection.OnNewRowNeeded()
at System.Windows.Forms.DataGridView.OnRowEnter(DataG ridViewCell&
dataGridViewCell, Int32 columnIndex, Int32 rowIndex, Boolean
canCreateNewRow, Boolean validationFailureOccurred)
at System.Windows.Forms.DataGridView.SetCurrentCellAd dressCore(Int32
columnIndex, Int32 rowIndex, Boolean setAnchorCellAddress, Boolean
validateCurrentCell, Boolean throughMouseClick)
at System.Windows.Forms.DataGridView.ProcessDownKeyIn ternal(Keys
keyData, Boolean& moved)
at System.Windows.Forms.DataGridView.ProcessDownKey(K eys keyData)
at
System.Windows.Forms.DataGridView.ProcessDataGridV iewKey(KeyEventArgs e)
at System.Windows.Forms.DataGridView.ProcessKeyPrevie w(Message& m)
at System.Windows.Forms.Control.ProcessKeyPreview(Mes sage& m)
at System.Windows.Forms.Control.ProcessKeyMessage(Mes sage& m)
at System.Windows.Forms.ComboBox.ChildWndProc(Message & m)
at
System.Windows.Forms.ComboBox.ComboBoxChildNativeW indow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallba ck(IntPtr hWnd,
Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchM essageW(MSG&
msg)
at
....
Jun 27 '08 #7
Sorry - I don't think I'm going to be able to debug that just from a
stacktrace, and I'm not in a desparate hurry to pick through your full
bespoke code... sorry again...

Marc
Jun 27 '08 #8
Marc,

I discovered that this occurs when all following conditions are met:

1. DataGridView contains single row
2. DataGridViewColumn column is DataGridViewComboBoxColumn
3. EditMode is EditOnEnter

In this case pressing up arrow in new row does *not* call BindingList
RemoveItem() method.

Is this .NET bug ? Any idea how to fix it ?

Andrus.
Jun 27 '08 #9
Following code reproduces DataGridView crash on edit.
Press down arrow, up arrow, down arrow. Exception occurs.

Any idea how to fix ?

Andrus.

using System;
using System.Windows.Forms;
using System.ComponentModel;

class Supplier {
public string Id { get; set; }
}

class Form1 : Form {
[STAThread]
static void Main() {
Application.Run(new Form1());
}

public Form1() {
DataGridView grid = new DataGridView();
// if this line is commented out, all is OK:
grid.EditMode = DataGridViewEditMode.EditOnEnter;
ComboBoxColumn comboBoxColumn = new ComboBoxColumn();
ComboBoxCell ComboBoxCell = new ComboBoxCell();
comboBoxColumn.CellTemplate = ComboBoxCell;
grid.Columns.Add(comboBoxColumn);
BindingList<Supplierl = new BindingList<Supplier>();
l.Add(new Supplier());
grid.DataSource = l;
Controls.Add(grid);
}

class ComboBoxColumn : DataGridViewComboBoxColumn { }

class ComboBoxCell : DataGridViewComboBoxCell {
public override Type EditType {
get {
return typeof(ComboBoxEditingControl);
}
}

}

class ComboBoxEditingControl : ComboBox, IDataGridViewEditingControl {
protected int rowIndex;
protected DataGridView dataGridView;
protected bool valueChanged = false;

protected override void OnTextChanged(EventArgs e) {
base.OnTextChanged(e);
NotifyDataGridViewOfValueChange();
}

protected virtual void NotifyDataGridViewOfValueChange() {
valueChanged = true;
if (dataGridView != null) {
dataGridView.NotifyCurrentCellDirty(true);
}
}

public Cursor EditingPanelCursor {
get {
return Cursors.IBeam;
}
}

public DataGridView EditingControlDataGridView {
get {
return dataGridView;
}
set {
dataGridView = value;
}
}

public object EditingControlFormattedValue {
set {
if (value.ToString() != Text) {
Text = value.ToString();
NotifyDataGridViewOfValueChange();
}
}

get {
return Text;
}
}

public object
GetEditingControlFormattedValue(DataGridViewDataEr rorContexts
context) {
return Text;
}

public void PrepareEditingControlForEdit(bool selectAll) { }

public bool RepositionEditingControlOnValueChange {
get {
return false;
}
}

public int EditingControlRowIndex {
get {
return rowIndex;
}

set {
rowIndex = value;
}
}

public void ApplyCellStyleToEditingControl(DataGridViewCellSty le
dataGridViewCellStyle) {
DropDownStyle = ComboBoxStyle.DropDown;
}

public bool EditingControlWantsInputKey(Keys keyData, bool
dataGridViewWantsInputKey) {
return !dataGridViewWantsInputKey;
}

public bool EditingControlValueChanged {

get {
return valueChanged;
}
set {
valueChanged = value;
}
}
}
}
Jun 27 '08 #10
I will look later; I can't promise anything...
Jun 27 '08 #11
Marc,
>I will look later; I can't promise anything...
Thank you.

I noticed that if I comment out OnTextChanged() override, exception does not
occur.
However this code is from MSDN sample.

Andrus.


Jun 27 '08 #12
Can you (briefly) remind me what the purpose of this custom column is?
I'm reaching the conclusion that (sample or not) trying to implement
this from scratch is going to be hard; can you not just modify the
behavior of the existing control? For example - if you just want to
support up/down keys etc:

class ComboBoxEditingControl : DataGridViewComboBoxEditingControl
{
private void ChangeUpDown(bool up)
{
DataGridViewCell cell =
EditingControlDataGridView.CurrentCell;
if (cell == null) return;

int row = cell.RowIndex, col = cell.ColumnIndex;
if (up) row--; else row++;
if (row >= 0 && row < EditingControlDataGridView.RowCount
&& EditingControlDataGridView.EndEdit())
{
cell = EditingControlDataGridView.Rows[row].Cells[col];
EditingControlDataGridView.CurrentCell = cell;
}
}
public override bool EditingControlWantsInputKey(Keys keyData,
bool dataGridViewWantsInputKey)
{
switch (keyData)
{
case Keys.Up:
BeginInvoke((MethodInvoker)delegate {
ChangeUpDown(true);
});
return true;
case Keys.Down:
BeginInvoke((MethodInvoker)delegate {
ChangeUpDown(false);
});
return true;
case Keys.Enter:
BeginInvoke((MethodInvoker)delegate {
EditingControlDataGridView.EndEdit(); });
return true;
case Keys.Escape:
BeginInvoke((MethodInvoker)delegate {
EditingControlDataGridView.CancelEdit(); });
return true;
default:
return base.EditingControlWantsInputKey(keyData,
dataGridViewWantsInputKey);
}
}
}
Jun 27 '08 #13
Marc,
Can you (briefly) remind me what the purpose of this custom column is?
Custom column is used to host virtual foreign key ComboBox.
There may be 50000 customers in customer table. So customer name combobox
data source should be populated dynamically.

I use subclassed DataGridViewComboBoxCell GetFormattedValue() event to
populate combobox datasource
on the fly by calling Combobox datasource bindinglist special
AddIfNotExists()
method:

protected override object GetFormattedValue(object value, int rowIndex, ref
DataGridViewCellStyle cellStyle,
TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter,
DataGridViewDataErrorContexts context) {

ComboBoxColumn comboBoxColumn = OwningColumn as ComboBoxColumn;

comboBoxColumn.PickList.AddIfNotExists(value);

return base.GetFormattedValue(value, rowIndex, ref cellStyle,
valueTypeConverter, formattedValueTypeConverter, context);

Custom combobox column implementation is required to allow grid to
host this combobox.
I havent way any other method to allow enter customers by name in grid.
I'm reaching the conclusion that (sample or not) trying to implement
this from scratch is going to be hard;
Probably DataGridView does not call ICancelAddNew.EndNew() method.
New is remains in uncommited state when AddNewCore() is called. AddNewCore()
throws Invalid Operation exception.
I think there must be simple one line fix which fixes this. Probably
something simple is missing or wrong in custom column implementation. Or is
it possible to call EndNew() method itself from this code ?
can you not just modify the behavior of the existing control?
Should I really add event hander to GetFormattedValue() method ? There are
also other methods which needs to be overridden.
Should I try to add event handlers into all places ? MSDN recomments
subclassing and overriding methods as preferred technique for this.
>For example - if you just want to
support up/down keys etc:
The goal is to allow enter data using foreign keys when lookup table is big
and
resides in server.

Andrus.

Jun 27 '08 #14
Call me crazy, but a drop-down isn't the first choice I'd use for
this!

I don't know where the problem is; normally, EndNew/CancelNew are used
correctly, but in the code you posted RemoveItem indeed doesn't get
called. I dont' know why.
Jun 27 '08 #15
Marc,
Call me crazy, but a drop-down isn't the first choice I'd use for
this!
What control I must use in grid ?
I need also show some butotn for active cell so user can can open picklist
using mouse.
Combobox has all required ui elements.
I don't know where the problem is; normally, EndNew/CancelNew are used
correctly, but in the code you posted RemoveItem indeed doesn't get
called. I dont' know why.
Should I check boolean field and issue CancelNew before calling AddNewCore()
if I detect that
previous new row is not committed ?

Andrus.
Jun 27 '08 #16
What control I must use in grid ?
Maybe a link label, and handle the even by presenting a sensible
search dialog?
*I need also show some butotn for active cell so user can can open picklist
using mouse.
Combobox has all required ui elements.
Fair enough...
Should I check boolean [snip]
I simply don't know. Sorry.

Marc
Jun 27 '08 #17
>What control I must use in grid ?
>Maybe a link label, and handle the even by presenting a sensible
search dialog?
There must be possibility to enter customer name from keyboard directly to
list.
So this requires to create separate linklabel column in grid. Is this
reasonable ?
I simply don't know. Sorry.
It seems that AddNewCore() calls ListChanged() event which confuses grid. I
fixed this by using

RaiseListChangedEvents = false;
row = base.AddNewCore() as T;
RaiseListChangedEvents = true;

Hope this is OK.

Andrus.
Jun 27 '08 #18
Attached solution to your message contains WPF code which looks the same as
in previous message

WPF: Custom control and resorce files in a different assembly.

I was unable to run this solution:

Error 1 Metadata file
'C:\CustomExpanderControl\TestHarnes\CustomExpande r\bin\Release\CustomControls.dll'
could not be found TestHarnes

Error 2 Cannot find the type 'res:CustomResources'. Note that type names are
case sensitive. Line 22 Position 27.
C:\CustomExpanderControl\TestHarnes\CustomExpander \Controls\TestExpander.xaml
22 27 CustomControls

This attachment seems not related to your question.

I'm using Marc code sample with one fix without issues.
I do'nt remember which issue I described in post you referenced.

Andrus.

"Ashley Childs" <as**********@hotmail.comwrote in message
news:e5**************@TK2MSFTNGP04.phx.gbl...
Andrus,

I have come the issue you outlined in this log and I would say it makes
the experience of developeing LINQ with DataGridViews very painful.
Please can you tell me if you managed to resplve this issue with you
last post and if so in which event did you place your code?
Jul 7 '08 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Scott Nonnenberg [MSFT] | last post by:
LINQ and C# 3.0 "Couldn't attend PDC but still want to talk to the C# team? This chat is your chance! Join the C# team to discuss the .NET Language Integrated Query Framework (LINQ) and newly...
0
by: Marshal | last post by:
I've just had a chance to review LINQ, DLinq, and XLinq, (which I only heard about last week after the PDC). The various LINQs actually seem to live up to expectations - Using query semantics to...
7
by: Chris | last post by:
I am a little confused. I have been reading about LINQ and it seems to imply LINQ is available in C# 3 but not in Visual Studio until the next release. I am a VB.net programmer but would still like...
18
by: martin | last post by:
I'm just wondering... Will it be possible to use C# 3.0 and Linq to objects without having our users download the .NET Framework 2.0 client? I really would like to use the C# 3.0 features, but I...
3
by: David Veeneman | last post by:
I've been hearing a lot about LINQ in connection with Orcas, the next release of VS.NET. Micorosoft touts LINQ as the Next Big Breakthrough, but it looks to me like further muddying of application...
4
by: Arthur Dent | last post by:
Hello all, I am trying to figure out how to do something in LINQ, IF I can even do it in LINQ. Online samples and such for LINQ is still a bit on the sketchy side. Here is what I want to...
22
by: paululvinius | last post by:
Hi! Testing som Linq-expressions and tried to measure performance and compare it to pre-Linq programming. The folloing two methods are functional equal but the non-Linq one is twice as fast....
5
by: =?Utf-8?B?bWljaGFlbCBzb3JlbnM=?= | last post by:
After having played around with LINQ and reading the literature on it I have not been successful in getting this to work so I am looking for some guidance: I want to find a hunk in a collection...
9
by: =?Utf-8?B?cmF1bGF2aQ==?= | last post by:
Hi all: after reading different places/sites about linq... I ran into these questions: 1. What framework do we need to run linq ? (does it depend on what version of visual studio we have?) how...
1
by: hrishy | last post by:
Hi Well wouldn't it be a lot easier to query and join a xml source with a relational source with LINQ capabilites in Python. Hmm what am i missing here is there a site that takes all LINQ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.