66using System . Linq ;
77using System . Media ;
88using System . Windows . Forms ;
9+ using JetBrains . Annotations ;
910using L10NSharp . UI ;
1011using SIL . Code ;
1112using SIL . Windows . Forms . Widgets . BetterGrid ;
@@ -54,8 +55,6 @@ private void Initialize()
5455 {
5556 _grid . Font = SystemFonts . MenuFont ;
5657
57- // TODO: Localize column headings
58-
5958 DataGridViewColumn col = BetterGrid . CreateTextBoxColumn ( "name" , "Name" ) ;
6059 col . Width = 150 ;
6160 _grid . Columns . Add ( col ) ;
@@ -74,7 +73,7 @@ private void Initialize()
7473
7574 _grid . AddRemoveRowColumn ( null , null ,
7675 null /* TODO: Enhance BetterGrid to be able to show tool tips in non-virtual mode */ ,
77- rowIndex => DeleteRow ( rowIndex ) ) ;
76+ DeleteRow ) ;
7877
7978 _grid . AllowUserToAddRows = true ;
8079 _grid . AllowUserToDeleteRows = true ;
@@ -88,15 +87,13 @@ private void Initialize()
8887 _grid . RowsRemoved += HandleGridRowsRemoved ;
8988 _grid . ColumnHeaderMouseClick += _grid_ColumnHeaderMouseClick ;
9089
91- if ( _model . ContributorsGridSettings != null )
92- _model . ContributorsGridSettings . InitializeGrid ( _grid ) ;
90+ _model . ContributorsGridSettings ? . InitializeGrid ( _grid ) ;
9391 }
9492
9593 // SP-874: Not able to open L10NSharp with Alt-Shift-click
96- void _grid_ColumnHeaderMouseClick ( object sender , DataGridViewCellMouseEventArgs e )
94+ private void _grid_ColumnHeaderMouseClick ( object sender , DataGridViewCellMouseEventArgs e )
9795 {
98- if ( ColumnHeaderMouseClick != null )
99- ColumnHeaderMouseClick ( sender , e ) ;
96+ ColumnHeaderMouseClick ? . Invoke ( sender , e ) ;
10097 }
10198
10299 /// ------------------------------------------------------------------------------------
@@ -107,28 +104,20 @@ void _grid_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs
107104 /// problem.
108105 /// </summary>
109106 /// ------------------------------------------------------------------------------------
110- private new bool DesignMode
111- {
112- get
113- {
114- return ( base . DesignMode || GetService ( typeof ( IDesignerHost ) ) != null ) ||
115- ( LicenseManager . UsageMode == LicenseUsageMode . Designtime ) ;
116- }
117- }
107+ private new bool DesignMode => base . DesignMode ||
108+ GetService ( typeof ( IDesignerHost ) ) != null ||
109+ LicenseManager . UsageMode == LicenseUsageMode . Designtime ;
118110
119111 /// ------------------------------------------------------------------------------------
120- public bool InEditMode
121- {
122- get { return _grid . IsCurrentRowDirty ; }
123- }
112+ [ PublicAPI ]
113+ public bool InEditMode => _grid . IsCurrentRowDirty ;
124114
125115 /// ------------------------------------------------------------------------------------
126- public bool InNewContributionRow
127- {
128- get { return ( _grid . CurrentCellAddress . Y == _grid . NewRowIndex ) ; }
129- }
116+ [ PublicAPI ]
117+ public bool InNewContributionRow => _grid . CurrentCellAddress . Y == _grid . NewRowIndex ;
130118
131119 /// ------------------------------------------------------------------------------------
120+ [ PublicAPI ]
132121 public Contribution GetCurrentContribution ( )
133122 {
134123 return GetContributionFromRow ( _grid . CurrentCellAddress . Y ) ;
@@ -174,14 +163,32 @@ void HandleGridMouseClick(object sender, MouseEventArgs e)
174163 return ;
175164 }
176165
166+ void SelectFirstCellInClickedRow ( ) => _grid . CurrentCell = _grid [ 0 , hi . RowIndex ] ;
167+
177168 // At this point we know the user clicked on a row heading. Now we
178169 // need to make sure the row they're leaving is in a valid state.
179170 if ( ValidatingContributor != null && _grid . CurrentCellAddress . Y >= 0 &&
180171 _grid . CurrentCellAddress . Y < _grid . RowCount - 1 )
181172 {
182- if ( _grid . CurrentCellAddress . Y == _model . Contributions . Count ( ) )
173+ if ( _grid . CurrentCellAddress . Y == _model . Contributions . Count )
183174 return ;
184175
176+ if ( _grid . IsDirty )
177+ {
178+ try
179+ {
180+ // This actually forces the commit/validation and will fail if the
181+ // current edit has the contribution in a bogus state.
182+ SelectFirstCellInClickedRow ( ) ;
183+ return ;
184+ }
185+ catch
186+ {
187+ SystemSounds . Beep . Play ( ) ;
188+ return ;
189+ }
190+ }
191+
185192 var contribution = _model . Contributions . ElementAt ( _grid . CurrentCellAddress . Y ) ;
186193 if ( ! GetIsValidContribution ( contribution ) )
187194 {
@@ -190,8 +197,7 @@ void HandleGridMouseClick(object sender, MouseEventArgs e)
190197 }
191198 }
192199
193- // Make the first cell current in the row the user clicked.
194- _grid . CurrentCell = _grid [ 0 , hi . RowIndex ] ;
200+ SelectFirstCellInClickedRow ( ) ;
195201 }
196202
197203 /// ------------------------------------------------------------------------------------
@@ -232,8 +238,7 @@ private void HandleGridRowValidating(object sender, DataGridViewCellCancelEventA
232238
233239 if ( ! string . IsNullOrEmpty ( kvp . Key ) )
234240 {
235- if ( _msgWindow == null )
236- _msgWindow = new FadingMessageWindow ( ) ;
241+ _msgWindow ??= new FadingMessageWindow ( ) ;
237242
238243 var dataGridViewColumn = _grid . Columns [ kvp . Key ] ;
239244 if ( dataGridViewColumn != null )
@@ -324,42 +329,40 @@ protected void HandleEditingControlShowing(object sender, DataGridViewEditingCon
324329 /// ------------------------------------------------------------------------------------
325330 void HandleRoleValueChanged ( object sender , EventArgs e )
326331 {
327- if ( _msgWindow != null )
328- _msgWindow . Close ( ) ;
332+ _msgWindow ? . Close ( ) ;
329333 }
330334
331335 /// ------------------------------------------------------------------------------------
332336 void HandleGridCellEndEdit ( object sender , DataGridViewCellEventArgs e )
333337 {
334338 var ctrl = _grid . Tag as Control ;
335339
340+ var txtBox = ctrl as TextBox ;
336341 // SP-793: Text should match case of autocomplete list
337- if ( e . ColumnIndex == 0 )
342+ if ( e . ColumnIndex == 0 && txtBox != null )
338343 {
339- var txtBox = ctrl as TextBox ;
340- if ( txtBox != null )
341- {
342- // is the current text an exact match for the autocomplete list?
343- var list = txtBox . AutoCompleteCustomSource . Cast < object > ( ) . ToList ( ) ;
344- var found = list . FirstOrDefault ( item => String . Equals ( item . ToString ( ) , txtBox . Text , StringComparison . CurrentCulture ) ) ;
344+ // is the current text an exact match for the autocomplete list?
345+ var list = txtBox . AutoCompleteCustomSource . Cast < object > ( ) . ToList ( ) ;
346+ var found = list . FirstOrDefault ( item =>
347+ String . Equals ( item . ToString ( ) , txtBox . Text , StringComparison . CurrentCulture ) ) ;
345348
346- if ( found == null )
349+ if ( found == null )
350+ {
351+ // is the current text a match except for case for the autocomplete list?
352+ found = list . FirstOrDefault ( item => String . Equals ( item . ToString ( ) ,
353+ txtBox . Text , StringComparison . CurrentCultureIgnoreCase ) ) ;
354+ if ( found != null )
347355 {
348- // is the current text a match except for case for the autocomplete list?
349- found = list . FirstOrDefault ( item => String . Equals ( item . ToString ( ) , txtBox . Text , StringComparison . CurrentCultureIgnoreCase ) ) ;
350- if ( found != null )
351- {
352- txtBox . Text = found . ToString ( ) ;
353- _grid . CurrentCell . Value = txtBox . Text ;
354- }
356+ txtBox . Text = found . ToString ( ) ;
357+ _grid . CurrentCell . Value = txtBox . Text ;
355358 }
356359 }
357360 }
358361
359- if ( ctrl is TextBox )
360- ctrl . KeyPress -= HandleCellEditBoxKeyPress ;
361- else if ( ctrl is ComboBox )
362- ( ( ComboBox ) ctrl ) . SelectedIndexChanged -= HandleRoleValueChanged ;
362+ if ( txtBox != null )
363+ txtBox . KeyPress -= HandleCellEditBoxKeyPress ;
364+ else if ( ctrl is ComboBox box )
365+ box . SelectedIndexChanged -= HandleRoleValueChanged ;
363366
364367 _grid . CellEndEdit -= HandleGridCellEndEdit ;
365368 _grid . Tag = null ;
@@ -399,15 +402,13 @@ public void SetColumnHeaderText(int columnIndex, string headerText)
399402
400403 /// <remarks>SP-874: Localize column headers</remarks>
401404 [ CLSCompliant ( false ) ]
405+ [ PublicAPI ]
402406 public void SetLocalizationExtender ( L10NSharpExtender extender )
403407 {
404408 extender . SetLocalizingId ( _grid , "ContributorsEditorGrid" ) ;
405409 }
406410
407411 /// <remarks>We need to be able to adjust the visual properties to match the hosting program</remarks>
408- public BetterGrid Grid
409- {
410- get { return _grid ; }
411- }
412+ public BetterGrid Grid => _grid ;
412413 }
413414}
0 commit comments