IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Framework .NET Discussion :

[DataGridView, Custom Column] InvalidOperationException


Sujet :

Framework .NET

  1. #1
    Membre expérimenté Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Points : 1 539
    Points
    1 539
    Par défaut [DataGridView, Custom Column] InvalidOperationException
    Le contexte :
    J'ai une classe Toto que voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Toto
    {
    	private NpgsqlTypes.NpgsqlInterval _interval;
     
    	public NpgsqlTypes.NpgsqlInterval Interval {
    		get { return _interval; }
    		set { _interval = value; }
    	}
    }
    On fait difficilement plus simple dans le cas de cette exception.

    Cette classe me sert de source de donnée pour un DataGridView, via un BindingSource et une BindingList<Toto>.

    J'ai à côté de ça une colonne customisée NpgsqlIntervalPickerColumn qui affiche un contrôle utilisateur NpgsqlIntervalPicker. Le NpgsqlIntervalPicker utilise la donnée de type NpgsqlInterval.
    Tous ces Types n'existaient pas, j'en avais besoin, je les ais donc créés. (Je peux fournir le code de ces types si nécessaire pour la résolution de ce problème).

    Le problème :
    Lors de l'édition de la dernière ligne contenant des données du contrôle DataGridView (c'est à dire pas la NewRow, mais celle juste avant), j'ai une exception qui survient plus ou moins aléatoirement.
    Si je n'ai qu'une seule ligne dans le DataGridView (donc 3 lignes en comptant la header et la newrow), l'exception surviendra toujours du premier coup.
    Si j'ai davantage de lignes, l'exception semble survenir aléatoirement avant 10 éditions successives (c'est à dire parfois après la 1ère édition, d'autres fois après la 5e, 6e, etc...)

    Le détail de l'exception :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    L'exception System.InvalidOperationException n'a pas été gérée
      Message="L'opération n'est pas valide en raison de l'état actuel de l'objet."
      Source="System.Windows.Forms"
      StackTrace:
           à System.Windows.Forms.DataGridView.DataGridViewDataConnection.ProcessListChanged(ListChangedEventArgs e)
           à System.Windows.Forms.DataGridView.DataGridViewDataConnection.currencyManager_ListChanged(Object sender, ListChangedEventArgs e)
           à System.Windows.Forms.CurrencyManager.OnListChanged(ListChangedEventArgs e)
           à System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
           à System.Windows.Forms.BindingSource.OnListChanged(ListChangedEventArgs e)
           à System.Windows.Forms.BindingSource.InnerList_ListChanged(Object sender, ListChangedEventArgs e)
           à System.ComponentModel.BindingList`1.OnListChanged(ListChangedEventArgs e)
           à System.ComponentModel.BindingList`1.InsertItem(Int32 index, T item)
           à System.Collections.ObjectModel.Collection`1.Add(T item)
           à System.ComponentModel.BindingList`1.AddNewCore()
           à System.ComponentModel.BindingList`1.System.ComponentModel.IBindingList.AddNew()
           à System.Windows.Forms.BindingSource.AddNew()
           à System.Windows.Forms.CurrencyManager.AddNew()
           à System.Windows.Forms.DataGridView.DataGridViewDataConnection.AddNew()
           à System.Windows.Forms.DataGridView.DataGridViewDataConnection.OnNewRowNeeded()
           à System.Windows.Forms.DataGridView.OnRowEnter(DataGridViewCell& dataGridViewCell, Int32 columnIndex, Int32 rowIndex, Boolean canCreateNewRow, Boolean validationFailureOccurred)
           à System.Windows.Forms.DataGridView.SetCurrentCellAddressCore(Int32 columnIndex, Int32 rowIndex, Boolean setAnchorCellAddress, Boolean validateCurrentCell, Boolean throughMouseClick)
           à System.Windows.Forms.DataGridView.ProcessDownKeyInternal(Keys keyData, Boolean& moved)
           à System.Windows.Forms.DataGridView.ProcessEnterKey(Keys keyData)
           à System.Windows.Forms.DataGridView.ProcessDialogKey(Keys keyData)
           à Helios.FixedDataGridView.ProcessDialogKey(Keys keyData) dans C:\Users\David\Projets\Helios\Helios\FixedDataGridView.cs:ligne 12
           à System.Windows.Forms.Control.ProcessDialogKey(Keys keyData)
           à System.Windows.Forms.ContainerControl.ProcessDialogKey(Keys keyData)
           à System.Windows.Forms.Control.ProcessDialogKey(Keys keyData)
           à System.Windows.Forms.ContainerControl.ProcessDialogKey(Keys keyData)
           à System.Windows.Forms.TextBoxBase.ProcessDialogKey(Keys keyData)
           à System.Windows.Forms.Control.PreProcessMessage(Message& msg)
           à System.Windows.Forms.Control.PreProcessControlMessageInternal(Control target, Message& msg)
           à System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)
           à System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FPreTranslateMessage(MSG& msg)
           à System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           à System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           à System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           à System.Windows.Forms.Application.Run(Form mainForm)
           à test.Program.Main() dans C:\Users\David\Projets\Helios\test\Program.cs:ligne 16
           à System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           à System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           à System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           à System.Threading.ThreadHelper.ThreadStart()
    J'ai cherché sur internet si d'autres avaient eu un souci similaire, mais il semble que ma situation soit suffisemment spécifique pour que cela ne soit pas le cas.
    Tout ce que j'ai trouvé d'approchant, c'est un "bug" du DataGridView avec la touche Echap (Keys.Escape).

    Alors, j'ai été farfouiller le code source du framework .NET avec reflector, et voici ce sur quoi je suis tombé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    [Designer("System.Windows.Forms.Design.DataGridViewDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), ClassInterface(ClassInterfaceType.AutoDispatch), DefaultEvent("CellContentClick"), ComplexBindingProperties("DataSource", "DataMember"), Docking(DockingBehavior.Ask), SRDescription("DescriptionDataGridView"), Editor("System.Windows.Forms.Design.DataGridViewComponentEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(ComponentEditor)), ComVisible(true)]
    public partial class DataGridView : Control, ISupportInitialize
    {
    	internal partial class DataGridViewDataConnection
    	{
    		private void ProcessListChanged(ListChangedEventArgs e) {
    			if (((e.ListChangedType == ListChangedType.PropertyDescriptorAdded) || (e.ListChangedType == ListChangedType.PropertyDescriptorDeleted)) || (e.ListChangedType == ListChangedType.PropertyDescriptorChanged)) {
    				this.dataConnectionState [2] = true;
    				try {
    					this.DataSourceMetaDataChanged();
    				} finally {
    					this.dataConnectionState [2] = false;
    				}
    			} else if (this.dataConnectionState [0x10000] != this.owner.AllowUserToAddRowsInternal) {
    				this.dataConnectionState [0x400] = true;
    				try {
    					this.owner.RefreshRows(!this.owner.InSortOperation);
    					this.owner.PushAllowUserToAddRows();
    				} finally {
    					this.ResetDataConnectionState();
    				}
    			} else if (this.dataConnectionState [4] || (this.owner.newRowIndex != e.NewIndex)) {
    				if ((e.ListChangedType == ListChangedType.ItemAdded) && (this.currencyManager.List.Count == (this.owner.AllowUserToAddRowsInternal ? (this.owner.Rows.Count - 1) : this.owner.Rows.Count))) {
    					if (this.dataConnectionState [0x1000] && this.dataConnectionState [0x2000]) {
    						this.dataConnectionState [0x4000] = true;
    					}
    				} else {
    					if (e.ListChangedType == ListChangedType.ItemDeleted) {
    						if ((this.dataConnectionState [0x1000] && this.dataConnectionState [0x4000]) && this.dataConnectionState [0x2000]) {
    							this.dataConnectionState [0x4000] = false;
    						} else {
    							if (!this.dataConnectionState [4] && this.dataConnectionState [0x8000]) {
    								this.dataConnectionState [0x400] = true;
    								try {
    									this.owner.RefreshRows(!this.owner.InSortOperation);
    									this.owner.PushAllowUserToAddRows();
    								} finally {
    									this.dataConnectionState [0x400] = false;
    								}
    								return;
    							}
    							if (this.currencyManager.List.Count == this.DataBoundRowsCount()) {
    								return;
    							}
    						}
    					}
    					this.dataConnectionState [0x10] = true;
    					try {
    						switch (e.ListChangedType) {
    							case ListChangedType.Reset: {
    									this.dataConnectionState [0x400] = true;
    									bool visible = this.owner.Visible;
    									if (visible) {
    										this.owner.BeginUpdateInternal();
    									}
    									try {
    										this.owner.RefreshRows(!this.owner.InSortOperation);
    										this.owner.PushAllowUserToAddRows();
    										this.ApplySortingInformationFromBackEnd();
    										goto Label_05A2;
    									} finally {
    										this.ResetDataConnectionState();
    										if (visible) {
    											this.owner.EndUpdateInternal(false);
    											this.owner.Invalidate(true);
    										}
    									}
    									break;
    								}
    							case ListChangedType.ItemAdded:
    								break;
    
    							case ListChangedType.ItemDeleted:
    								this.owner.Rows.RemoveAtInternal(e.NewIndex, true);
    								this.dataConnectionState [0x2000] = false;
    								goto Label_05A2;
    
    							case ListChangedType.ItemMoved: {
    									int lo = Math.Min(e.OldIndex, e.NewIndex);
    									int hi = Math.Max(e.OldIndex, e.NewIndex);
    									this.owner.InvalidateRows(lo, hi);
    									goto Label_05A2;
    								}
    							case ListChangedType.ItemChanged: {
    									string name = null;
    									if (e.PropertyDescriptor != null) {
    										name = e.PropertyDescriptor.Name;
    									}
    									for (int i = 0 ; i < this.owner.Columns.Count ; i++) {
    										DataGridViewColumn column = this.owner.Columns [i];
    										if (column.Visible && column.IsDataBound) {
    											if (!string.IsNullOrEmpty(name)) {
    												if (string.Compare(column.DataPropertyName, name, true, CultureInfo.InvariantCulture) == 0) {
    													this.owner.OnCellCommonChange(i, e.NewIndex);
    												}
    											} else {
    												this.owner.OnCellCommonChange(i, e.NewIndex);
    											}
    										}
    									}
    									if ((this.owner.CurrentCellAddress.Y == e.NewIndex) && this.owner.IsCurrentCellInEditMode) {
    										this.owner.RefreshEdit();
    									}
    									goto Label_05A2;
    								}
    							default:
    								goto Label_05A2;
    						}
    						if ((this.owner.NewRowIndex != -1) && (e.NewIndex == this.owner.Rows.Count)) {
    							throw new InvalidOperationException();
    						}
    						this.owner.Rows.InsertInternal(e.NewIndex, this.owner.RowTemplateClone, true);
    					Label_05A2:
    						if (((this.owner.Rows.Count > 0) && !this.dataConnectionState [8]) && !this.owner.InSortOperation) {
    							this.MatchCurrencyManagerPosition(false, e.ListChangedType == ListChangedType.Reset);
    						}
    					} finally {
    						this.dataConnectionState [0x10] = false;
    					}
    				}
    			} else if (e.ListChangedType == ListChangedType.ItemAdded) {
    				if (!this.dataConnectionState [0x200] && !this.dataConnectionState [0x100]) {
    					if (this.owner.Columns.Count > 0) {
    						do {
    							this.owner.newRowIndex = -1;
    							this.owner.AddNewRow(false);
    						}
    						while (this.DataBoundRowsCount() < this.currencyManager.Count);
    					}
    					this.dataConnectionState [4] = true;
    					this.MatchCurrencyManagerPosition(true, true);
    				}
    			} else if (e.ListChangedType == ListChangedType.ItemDeleted) {
    				if (this.dataConnectionState [0x40]) {
    					this.owner.PopulateNewRowWithDefaultValues();
    				} else {
    					if (this.dataConnectionState [0x8000] || this.dataConnectionState [0x200]) {
    						this.dataConnectionState [0x400] = true;
    						try {
    							this.owner.RefreshRows(!this.owner.InSortOperation);
    							this.owner.PushAllowUserToAddRows();
    							return;
    						} finally {
    							this.dataConnectionState [0x400] = false;
    						}
    					}
    					if (this.dataConnectionState [0x1000] && (this.currencyManager.List.Count == 0)) {
    						this.AddNew();
    					}
    				}
    			}
    		}
    	}
    }
    J'attire votre attention sur le code en gras, c'est de là que provient l'exception.

    On a donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if((this.owner.NewRowIndex != -1) && (e.NewIndex == this.owner.Rows.Count))throw new InvalidOperationException();
    Sachant que :
    • DataGridView.NewRowIndex est toujours différent de -1, excepté dans le cas où l'ajout de lignes a été désactivé dans le DataGridView (ce qui n'est pas le cas ici)
    • e.NewIndex ne devrait jamais être égal à this.owner.Rows.Count dans le cas de l'édition d'une ligne (ce qui est le cas ici) puisqu'on ne peut pas éditer une ligne qui n'existe pas et que les index des lignes existantes vont de 0 à this.owner.Rows.Count - 1 (et même - 2, si on enlève NewRow)

    Comment cette exception peut-elle se produire ??!

  2. #2
    Membre expérimenté Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Points : 1 539
    Points
    1 539
    Par défaut
    Je devrais arrêter de réfléchir après minuit moi...

    En fait le souci ne vient pas de l'édition d'une ligne, il vient de l'ajout d'une ligne (ce qui arrive quand on met en surbrillance la dernière ligne (newrow) de la datagridview).

  3. #3
    Membre expérimenté Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Points : 1 539
    Points
    1 539
    Par défaut
    Je viens de résoudre mon problème.... C'était vraiment débile... -_- grmblbl...

    Dans le genre "oublié un point virgule" (là c'était "abonné à un événement en trop")....

  4. #4
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    J'ai exactement le même probleme. même cas de figure lors d'une validation sur une DataGridView.
    Peux-tu expliquer la solution apportée ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 03/07/2013, 12h46
  2. DataGridView CheckBox Column : Mise en garde
    Par olibara dans le forum C#
    Réponses: 2
    Dernier message: 23/03/2009, 13h43
  3. datagridview vertical column
    Par fontome_ 123 dans le forum VB.NET
    Réponses: 5
    Dernier message: 01/05/2008, 13h32
  4. Création d'un Datagridview custom et colonne custom
    Par Yogy dans le forum Windows Forms
    Réponses: 7
    Dernier message: 06/03/2008, 15h16
  5. Réponses: 3
    Dernier message: 06/02/2008, 22h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo