Upgrade EEPlus

This commit is contained in:
CreepyCrafter24 2020-02-29 13:20:21 +01:00
parent f243bcc5f9
commit 8a44670977
15 changed files with 510 additions and 587 deletions

0
.idea/.gitignore vendored Normal file
View File

View File

@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="true" />
</component>
<component name="ProjectNotificationSettings">
<option name="askShowProject" value="false" />
</component>
</project>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ContentModelUserStore">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MarkdownProjectSettings">
<PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" synchronizePreviewPosition="true" highlightPreviewType="LINE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="true" showSelectionInPreview="true" lastLayoutSetsDefault="false">
<PanelProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" />
</PanelProvider>
</PreviewSettings>
<ParserSettings gitHubSyntaxChange="false" emojiShortcuts="0" emojiImages="0">
<PegdownExtensions>
<option name="ABBREVIATIONS" value="false" />
<option name="ANCHORLINKS" value="false" />
<option name="ASIDE" value="false" />
<option name="ATXHEADERSPACE" value="false" />
<option name="AUTOLINKS" value="false" />
<option name="DEFINITIONS" value="false" />
<option name="DEFINITION_BREAK_DOUBLE_BLANK_LINE" value="false" />
<option name="EXTANCHORLINKS" value="false" />
<option name="EXTANCHORLINKS_WRAP" value="false" />
<option name="FENCED_CODE_BLOCKS" value="false" />
<option name="FOOTNOTES" value="false" />
<option name="HARDWRAPS" value="false" />
<option name="HTML_DEEP_PARSER" value="false" />
<option name="INSERTED" value="false" />
<option name="INTELLIJ_DUMMY_IDENTIFIER" value="false" />
<option name="MULTI_LINE_IMAGE_URLS" value="false" />
<option name="QUOTES" value="false" />
<option name="RELAXEDHRULES" value="false" />
<option name="SMARTS" value="false" />
<option name="STRIKETHROUGH" value="false" />
<option name="SUBSCRIPT" value="false" />
<option name="SUPERSCRIPT" value="false" />
<option name="SUPPRESS_HTML_BLOCKS" value="false" />
<option name="SUPPRESS_INLINE_HTML" value="false" />
<option name="TABLES" value="false" />
<option name="TASKLISTITEMS" value="false" />
<option name="TOC" value="false" />
<option name="WIKILINKS" value="false" />
</PegdownExtensions>
<ParserOptions>
<option name="ADMONITION_EXT" value="false" />
<option name="ATTRIBUTES_EXT" value="false" />
<option name="COMMONMARK_LISTS" value="false" />
<option name="DUMMY" value="false" />
<option name="EMOJI_SHORTCUTS" value="false" />
<option name="ENUMERATED_REFERENCES_EXT" value="false" />
<option name="FLEXMARK_FRONT_MATTER" value="false" />
<option name="GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA" value="false" />
<option name="GFM_TABLE_RENDERING" value="false" />
<option name="GITBOOK_URL_ENCODING" value="false" />
<option name="GITHUB_LISTS" value="false" />
<option name="GITHUB_WIKI_LINKS" value="false" />
<option name="GITLAB_EXT" value="false" />
<option name="GITLAB_MATH_EXT" value="false" />
<option name="GITLAB_MERMAID_EXT" value="false" />
<option name="HEADER_ID_NON_ASCII_TO_LOWERCASE" value="false" />
<option name="HEADER_ID_NO_DUPED_DASHES" value="false" />
<option name="JEKYLL_FRONT_MATTER" value="false" />
<option name="MACROS_EXT" value="false" />
<option name="NO_TEXT_ATTRIBUTES" value="false" />
<option name="PARSE_HTML_ANCHOR_ID" value="false" />
<option name="PLANTUML_FENCED_CODE" value="false" />
<option name="PRODUCTION_SPEC_PARSER" value="false" />
<option name="PUML_FENCED_CODE" value="false" />
<option name="SIM_TOC_BLANK_LINE_SPACER" value="false" />
<option name="SPACE_IN_LINK_URLS" value="false" />
</ParserOptions>
</ParserSettings>
<HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" addPageHeader="false" imageUriSerials="false" addDocTypeHtml="true" noParaTags="false" plantUmlConversion="0">
<GeneratorProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.text.html.generator" providerName="Unmodified HTML Generator" />
</GeneratorProvider>
<headerTop />
<headerBottom />
<bodyTop />
<bodyBottom />
</HtmlSettings>
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssUriSerial="true" isCssTextEnabled="false" isDynamicPageWidth="true">
<StylesheetProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.text.html.css" providerName="No Stylesheet" />
</StylesheetProvider>
<ScriptProviders />
<cssText />
<cssUriHistory />
</CssSettings>
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RiderProjectSettingsUpdater">
<option name="vcsConfiguration" value="1" />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -3,25 +3,13 @@ using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace GradeCalc
{
public class DataGridViewNumericUpDownCell : DataGridViewTextBoxCell
{
// Used in KeyEntersEditMode function
[System.Runtime.InteropServices.DllImport("USER32.DLL", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern short VkKeyScan(char key);
// Used in TranslateAlignment function
private static readonly DataGridViewContentAlignment anyRight = DataGridViewContentAlignment.TopRight |
DataGridViewContentAlignment.MiddleRight |
DataGridViewContentAlignment.BottomRight;
private static readonly DataGridViewContentAlignment anyCenter = DataGridViewContentAlignment.TopCenter |
DataGridViewContentAlignment.MiddleCenter |
DataGridViewContentAlignment.BottomCenter;
// Default dimensions of the static rendering bitmap used for the painting of the non-edited cells
private const int DATAGRIDVIEWNUMERICUPDOWNCELL_defaultRenderingBitmapWidth = 100;
@ -42,24 +30,31 @@ namespace GradeCalc
// Default value of the ThousandsSeparator property
internal const bool DATAGRIDVIEWNUMERICUPDOWNCELL_defaultThousandsSeparator = false;
// Used in TranslateAlignment function
private static readonly DataGridViewContentAlignment anyRight = DataGridViewContentAlignment.TopRight |
DataGridViewContentAlignment.MiddleRight |
DataGridViewContentAlignment.BottomRight;
private static readonly DataGridViewContentAlignment anyCenter = DataGridViewContentAlignment.TopCenter |
DataGridViewContentAlignment.MiddleCenter |
DataGridViewContentAlignment.BottomCenter;
// Type of this cell's editing control
private static Type defaultEditType = typeof(DataGridViewNumericUpDownEditingControl);
private static readonly Type defaultEditType = typeof(DataGridViewNumericUpDownEditingControl);
// Type of this cell's value. The formatted value type is string, the same as the base class DataGridViewTextBoxCell
private static Type defaultValueType = typeof(decimal);
private static readonly Type defaultValueType = typeof(decimal);
// The bitmap used to paint the non-edited cells via a call to NumericUpDown.DrawToBitmap
[ThreadStatic]
private static Bitmap renderingBitmap;
[ThreadStatic] private static Bitmap renderingBitmap;
// The NumericUpDown control used to paint the non-edited cells via a call to NumericUpDown.DrawToBitmap
[ThreadStatic]
private static NumericUpDown paintingNumericUpDown;
[ThreadStatic] private static NumericUpDown paintingNumericUpDown;
private int decimalPlaces; // Caches the value of the DecimalPlaces property
private decimal increment; // Caches the value of the Increment property
private decimal minimum; // Caches the value of the Minimum property
private decimal maximum; // Caches the value of the Maximum property
private decimal minimum; // Caches the value of the Minimum property
private bool thousandsSeparator; // Caches the value of the ThousandsSeparator property
/// <summary>
@ -69,9 +64,8 @@ namespace GradeCalc
{
// Create a thread specific bitmap used for the painting of the non-edited cells
if (renderingBitmap == null)
{
renderingBitmap = new Bitmap(DATAGRIDVIEWNUMERICUPDOWNCELL_defaultRenderingBitmapWidth, DATAGRIDVIEWNUMERICUPDOWNCELL_defaultRenderingBitmapHeight);
}
renderingBitmap = new Bitmap(DATAGRIDVIEWNUMERICUPDOWNCELL_defaultRenderingBitmapWidth,
DATAGRIDVIEWNUMERICUPDOWNCELL_defaultRenderingBitmapHeight);
// Create a thread specific NumericUpDown control used for the painting of the non-edited cells
if (paintingNumericUpDown == null)
@ -99,15 +93,13 @@ namespace GradeCalc
]
public int DecimalPlaces
{
get {
return decimalPlaces;
}
get => decimalPlaces;
set {
if (value < 0 || value > 99)
set
{
throw new ArgumentOutOfRangeException("The DecimalPlaces property cannot be smaller than 0 or larger than 99.");
}
if (value < 0 || value > 99)
throw new ArgumentOutOfRangeException(
"The DecimalPlaces property cannot be smaller than 0 or larger than 99.");
if (decimalPlaces != value)
{
SetDecimalPlaces(RowIndex, value);
@ -119,37 +111,25 @@ namespace GradeCalc
/// <summary>
/// Returns the current DataGridView EditingControl as a DataGridViewNumericUpDownEditingControl control
/// </summary>
private DataGridViewNumericUpDownEditingControl EditingNumericUpDown
{
get {
return DataGridView.EditingControl as DataGridViewNumericUpDownEditingControl;
}
}
private DataGridViewNumericUpDownEditingControl EditingNumericUpDown =>
DataGridView.EditingControl as DataGridViewNumericUpDownEditingControl;
/// <summary>
/// Define the type of the cell's editing control
/// </summary>
public override Type EditType
{
get {
return defaultEditType; // the type is DataGridViewNumericUpDownEditingControl
}
}
public override Type EditType => defaultEditType; // the type is DataGridViewNumericUpDownEditingControl
/// <summary>
/// The Increment property replicates the one from the NumericUpDown control
/// </summary>
public decimal Increment
{
get {
return increment;
}
get => increment;
set {
if (value < (decimal)0.0)
set
{
if (value < (decimal) 0.0)
throw new ArgumentOutOfRangeException("The Increment property cannot be smaller than 0.");
}
SetIncrement(RowIndex, value);
// No call to OnCommonChange is needed since the increment value does not affect the rendering of the cell.
}
@ -160,11 +140,10 @@ namespace GradeCalc
/// </summary>
public decimal Maximum
{
get {
return maximum;
}
get => maximum;
set {
set
{
if (maximum != value)
{
SetMaximum(RowIndex, value);
@ -178,11 +157,10 @@ namespace GradeCalc
/// </summary>
public decimal Minimum
{
get {
return minimum;
}
get => minimum;
set {
set
{
if (minimum != value)
{
SetMinimum(RowIndex, value);
@ -199,11 +177,10 @@ namespace GradeCalc
]
public bool ThousandsSeparator
{
get {
return thousandsSeparator;
}
get => thousandsSeparator;
set {
set
{
if (thousandsSeparator != value)
{
SetThousandsSeparator(RowIndex, value);
@ -217,16 +194,18 @@ namespace GradeCalc
/// </summary>
public override Type ValueType
{
get {
Type valueType = base.ValueType;
if (valueType != null)
get
{
return valueType;
}
Type valueType = base.ValueType;
if (valueType != null) return valueType;
return defaultValueType;
}
}
// Used in KeyEntersEditMode function
[DllImport("USER32.DLL", CharSet = CharSet.Auto)]
private static extern short VkKeyScan(char key);
/// <summary>
/// Clones a DataGridViewNumericUpDownCell cell, copies all the custom properties.
/// </summary>
@ -250,14 +229,8 @@ namespace GradeCalc
private decimal Constrain(decimal value)
{
Debug.Assert(minimum <= maximum);
if (value < minimum)
{
value = minimum;
}
if (value > maximum)
{
value = maximum;
}
if (value < minimum) value = minimum;
if (value > maximum) value = maximum;
return value;
}
@ -271,9 +244,7 @@ namespace GradeCalc
{
DataGridView dataGridView = DataGridView;
if (dataGridView == null || dataGridView.EditingControl == null)
{
throw new InvalidOperationException("Cell is detached or its grid has no editing control.");
}
NumericUpDown numericUpDown = dataGridView.EditingControl as NumericUpDown;
if (numericUpDown != null)
@ -284,10 +255,7 @@ namespace GradeCalc
// Here the undo buffer of the TextBox inside the NumericUpDown control gets cleared to avoid
// interferences between the editing sessions.
TextBox textBox = numericUpDown.Controls[1] as TextBox;
if (textBox != null)
{
textBox.ClearUndo();
}
if (textBox != null) textBox.ClearUndo();
}
base.DetachEditingControl();
@ -296,7 +264,8 @@ namespace GradeCalc
/// <summary>
/// Adjusts the location and size of the editing control given the alignment characteristics of the cell
/// </summary>
private Rectangle GetAdjustedEditingControlBounds(Rectangle editingControlBounds, DataGridViewCellStyle cellStyle)
private Rectangle GetAdjustedEditingControlBounds(Rectangle editingControlBounds,
DataGridViewCellStyle cellStyle)
{
// Add a 1 pixel padding on the left and right of the editing control
editingControlBounds.X += 1;
@ -305,7 +274,6 @@ namespace GradeCalc
// Adjust the vertical location of the editing control:
int preferredHeight = cellStyle.Font.Height + 3;
if (preferredHeight < editingControlBounds.Height)
{
switch (cellStyle.Alignment)
{
case DataGridViewContentAlignment.MiddleLeft:
@ -320,7 +288,6 @@ namespace GradeCalc
editingControlBounds.Y += editingControlBounds.Height - preferredHeight;
break;
}
}
return editingControlBounds;
}
@ -329,19 +296,16 @@ namespace GradeCalc
/// Customized implementation of the GetErrorIconBounds function in order to draw the potential
/// error icon next to the up/down buttons and not on top of them.
/// </summary>
protected override Rectangle GetErrorIconBounds(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
protected override Rectangle GetErrorIconBounds(Graphics graphics, DataGridViewCellStyle cellStyle,
int rowIndex)
{
const int ButtonsWidth = 16;
Rectangle errorIconBounds = base.GetErrorIconBounds(graphics, cellStyle, rowIndex);
if (DataGridView.RightToLeft == RightToLeft.Yes)
{
errorIconBounds.X = errorIconBounds.Left + ButtonsWidth;
}
else
{
errorIconBounds.X = errorIconBounds.Left - ButtonsWidth;
}
return errorIconBounds;
}
@ -357,19 +321,18 @@ namespace GradeCalc
DataGridViewDataErrorContexts context)
{
// By default, the base implementation converts the Decimal 1234.5 into the string "1234.5"
object formattedValue = base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context);
object formattedValue = base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter,
formattedValueTypeConverter, context);
string formattedNumber = formattedValue as string;
if (!string.IsNullOrEmpty(formattedNumber) && value != null)
{
decimal unformattedDecimal = Convert.ToDecimal(value);
decimal formattedDecimal = Convert.ToDecimal(formattedNumber);
if (unformattedDecimal == formattedDecimal)
{
// The base implementation of GetFormattedValue (which triggers the CellFormatting event) did nothing else than
// the typical 1234.5 to "1234.5" conversion. But depending on the values of ThousandsSeparator and DecimalPlaces,
// this may not be the actual string displayed. The real formatted value may be "1,234.500"
return formattedDecimal.ToString((ThousandsSeparator ? "N" : "F") + DecimalPlaces.ToString());
}
return formattedDecimal.ToString((ThousandsSeparator ? "N" : "F") + DecimalPlaces);
}
return formattedValue;
}
@ -378,12 +341,10 @@ namespace GradeCalc
/// Custom implementation of the GetPreferredSize function. This implementation uses the preferred size of the base
/// DataGridViewTextBoxCell cell and adds room for the up/down buttons.
/// </summary>
protected override Size GetPreferredSize(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize)
protected override Size GetPreferredSize(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex,
Size constraintSize)
{
if (DataGridView == null)
{
return new Size(-1, -1);
}
if (DataGridView == null) return new Size(-1, -1);
Size preferredSize = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize);
if (constraintSize.Width == 0)
@ -400,7 +361,8 @@ namespace GradeCalc
/// at the beginning of an editing session. It makes sure that the properties of the NumericUpDown editing control are
/// set according to the cell properties.
/// </summary>
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue,
DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
NumericUpDown numericUpDown = DataGridView.EditingControl as NumericUpDown;
@ -414,15 +376,11 @@ namespace GradeCalc
numericUpDown.ThousandsSeparator = ThousandsSeparator;
string initialFormattedValueStr = initialFormattedValue as string;
if (initialFormattedValueStr == null)
{
numericUpDown.Text = string.Empty;
}
else
{
numericUpDown.Text = initialFormattedValueStr;
}
}
}
/// <summary>
/// Custom implementation of the KeyEntersEditMode function. This function is called by the DataGridView control
@ -435,18 +393,14 @@ namespace GradeCalc
Keys negativeSignKey = Keys.None;
string negativeSignStr = numberFormatInfo.NegativeSign;
if (!string.IsNullOrEmpty(negativeSignStr) && negativeSignStr.Length == 1)
{
negativeSignKey = (Keys) VkKeyScan(negativeSignStr[0]);
}
if ((char.IsDigit((char) e.KeyCode) ||
e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9 ||
(e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9) ||
negativeSignKey == e.KeyCode ||
Keys.Subtract == e.KeyCode) &&
!e.Shift && !e.Alt && !e.Control)
{
return true;
}
return false;
}
@ -460,16 +414,13 @@ namespace GradeCalc
if (DataGridView != null && !DataGridView.IsDisposed && !DataGridView.Disposing)
{
if (RowIndex == -1)
{
// Invalidate and autosize column
DataGridView.InvalidateColumn(ColumnIndex);
// TODO: Add code to autosize the cell's column, the rows, the column headers
// and the row headers depending on their autosize settings.
// The DataGridView control does not expose a public method that takes care of this.
}
else
{
// The DataGridView control exposes a public method called UpdateCellValue
// that invalidates the cell so that it gets repainted and also triggers all
// the necessary autosizing: the cell's column and/or row, the column headers
@ -477,7 +428,6 @@ namespace GradeCalc
DataGridView.UpdateCellValue(ColumnIndex, RowIndex);
}
}
}
/// <summary>
/// Determines whether this cell, at the given row index, shows the grid's editing control or not.
@ -485,32 +435,31 @@ namespace GradeCalc
/// </summary>
private bool OwnsEditingNumericUpDown(int rowIndex)
{
if (rowIndex == -1 || DataGridView == null)
{
return false;
}
DataGridViewNumericUpDownEditingControl numericUpDownEditingControl = DataGridView.EditingControl as DataGridViewNumericUpDownEditingControl;
return numericUpDownEditingControl != null && rowIndex == ((IDataGridViewEditingControl)numericUpDownEditingControl).EditingControlRowIndex;
if (rowIndex == -1 || DataGridView == null) return false;
DataGridViewNumericUpDownEditingControl numericUpDownEditingControl =
DataGridView.EditingControl as DataGridViewNumericUpDownEditingControl;
return numericUpDownEditingControl != null && rowIndex ==
((IDataGridViewEditingControl) numericUpDownEditingControl).EditingControlRowIndex;
}
/// <summary>
/// Custom paints the cell. The base implementation of the DataGridViewTextBoxCell type is called first,
/// dropping the icon error and content foreground parts. Those two parts are painted by this custom implementation.
/// In this sample, the non-edited NumericUpDown control is painted by using a call to Control.DrawToBitmap. This is
/// an easy solution for painting controls but it's not necessarily the most performant. An alternative would be to paint
/// an easy solution for painting controls but it's not necessarily the most performant. An alternative would be to
/// paint
/// the NumericUpDown control piece by piece (text and up/down buttons).
/// </summary>
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState,
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
DataGridViewElementStates cellState,
object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
if (DataGridView == null)
{
return;
}
if (DataGridView == null) return;
// First paint the borders and background of the cell.
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle,
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText,
cellStyle, advancedBorderStyle,
paintParts & ~(DataGridViewPaintParts.ErrorIcon | DataGridViewPaintParts.ContentForeground));
Point ptCurrentCell = DataGridView.CurrentCellAddress;
@ -533,13 +482,9 @@ namespace GradeCalc
if (cellStyle.Padding != Padding.Empty)
{
if (DataGridView.RightToLeft == RightToLeft.Yes)
{
valBounds.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top);
}
else
{
valBounds.Offset(cellStyle.Padding.Left, cellStyle.Padding.Top);
}
valBounds.Width -= cellStyle.Padding.Horizontal;
valBounds.Height -= cellStyle.Padding.Vertical;
}
@ -557,9 +502,7 @@ namespace GradeCalc
}
// Make sure the NumericUpDown control is parented to a visible control
if (paintingNumericUpDown.Parent == null || !paintingNumericUpDown.Parent.Visible)
{
paintingNumericUpDown.Parent = DataGridView;
}
// Set all the relevant properties
paintingNumericUpDown.TextAlign = TranslateAlignment(cellStyle.Alignment);
paintingNumericUpDown.DecimalPlaces = DecimalPlaces;
@ -573,20 +516,14 @@ namespace GradeCalc
Color backColor;
if (PartPainted(paintParts, DataGridViewPaintParts.SelectionBackground) && cellSelected)
{
backColor = cellStyle.SelectionBackColor;
}
else
{
backColor = cellStyle.BackColor;
}
if (PartPainted(paintParts, DataGridViewPaintParts.Background))
{
if (backColor.A < 255)
{
// The NumericUpDown control does not support transparent back colors
backColor = Color.FromArgb(255, backColor);
}
paintingNumericUpDown.BackColor = backColor;
}
// Finally paint the NumericUpDown control
@ -599,21 +536,17 @@ namespace GradeCalc
}
}
if (PartPainted(paintParts, DataGridViewPaintParts.ErrorIcon))
{
// Paint the potential error icon on top of the NumericUpDown control
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText,
cellStyle, advancedBorderStyle, DataGridViewPaintParts.ErrorIcon);
}
}
}
/// <summary>
/// Little utility function called by the Paint function to see if a particular part needs to be painted.
/// </summary>
private static bool PartPainted(DataGridViewPaintParts paintParts, DataGridViewPaintParts paintPart)
{
return (paintParts & paintPart) != 0;
}
private static bool PartPainted(DataGridViewPaintParts paintParts, DataGridViewPaintParts paintPart) =>
(paintParts & paintPart) != 0;
/// <summary>
/// Custom implementation of the PositionEditingControl method called by the DataGridView control when it
@ -652,10 +585,7 @@ namespace GradeCalc
{
Debug.Assert(value >= 0 && value <= 99);
decimalPlaces = value;
if (OwnsEditingNumericUpDown(rowIndex))
{
EditingNumericUpDown.DecimalPlaces = value;
}
if (OwnsEditingNumericUpDown(rowIndex)) EditingNumericUpDown.DecimalPlaces = value;
}
/// Utility function that sets a new value for the Increment property of the cell. This function is used by
@ -665,10 +595,7 @@ namespace GradeCalc
{
Debug.Assert(value >= (decimal) 0.0);
increment = value;
if (OwnsEditingNumericUpDown(rowIndex))
{
EditingNumericUpDown.Increment = value;
}
if (OwnsEditingNumericUpDown(rowIndex)) EditingNumericUpDown.Increment = value;
}
/// Utility function that sets a new value for the Maximum property of the cell. This function is used by
@ -679,25 +606,16 @@ namespace GradeCalc
internal void SetMaximum(int rowIndex, decimal value)
{
maximum = value;
if (minimum > maximum)
{
minimum = maximum;
}
if (minimum > maximum) minimum = maximum;
object cellValue = GetValue(rowIndex);
if (cellValue != null)
{
decimal currentValue = Convert.ToDecimal(cellValue);
decimal constrainedValue = Constrain(currentValue);
if (constrainedValue != currentValue)
{
SetValue(rowIndex, constrainedValue);
}
if (constrainedValue != currentValue) SetValue(rowIndex, constrainedValue);
}
Debug.Assert(maximum == value);
if (OwnsEditingNumericUpDown(rowIndex))
{
EditingNumericUpDown.Maximum = value;
}
if (OwnsEditingNumericUpDown(rowIndex)) EditingNumericUpDown.Maximum = value;
}
/// Utility function that sets a new value for the Minimum property of the cell. This function is used by
@ -708,25 +626,16 @@ namespace GradeCalc
internal void SetMinimum(int rowIndex, decimal value)
{
minimum = value;
if (minimum > maximum)
{
maximum = value;
}
if (minimum > maximum) maximum = value;
object cellValue = GetValue(rowIndex);
if (cellValue != null)
{
decimal currentValue = Convert.ToDecimal(cellValue);
decimal constrainedValue = Constrain(currentValue);
if (constrainedValue != currentValue)
{
SetValue(rowIndex, constrainedValue);
}
if (constrainedValue != currentValue) SetValue(rowIndex, constrainedValue);
}
Debug.Assert(minimum == value);
if (OwnsEditingNumericUpDown(rowIndex))
{
EditingNumericUpDown.Minimum = value;
}
if (OwnsEditingNumericUpDown(rowIndex)) EditingNumericUpDown.Minimum = value;
}
/// Utility function that sets a new value for the ThousandsSeparator property of the cell. This function is used by
@ -737,38 +646,28 @@ namespace GradeCalc
internal void SetThousandsSeparator(int rowIndex, bool value)
{
thousandsSeparator = value;
if (OwnsEditingNumericUpDown(rowIndex))
{
EditingNumericUpDown.ThousandsSeparator = value;
}
if (OwnsEditingNumericUpDown(rowIndex)) EditingNumericUpDown.ThousandsSeparator = value;
}
/// <summary>
/// Returns a standard textual representation of the cell.
/// </summary>
public override string ToString()
{
return "DataGridViewNumericUpDownCell { ColumnIndex=" + ColumnIndex.ToString(CultureInfo.CurrentCulture) + ", RowIndex=" + RowIndex.ToString(CultureInfo.CurrentCulture) + " }";
}
public override string ToString() => "DataGridViewNumericUpDownCell { ColumnIndex=" +
ColumnIndex.ToString(CultureInfo.CurrentCulture) + ", RowIndex=" +
RowIndex.ToString(CultureInfo.CurrentCulture) + " }";
/// <summary>
/// Little utility function used by both the cell and column types to translate a DataGridViewContentAlignment value into
/// Little utility function used by both the cell and column types to translate a DataGridViewContentAlignment value
/// into
/// a HorizontalAlignment value.
/// </summary>
internal static HorizontalAlignment TranslateAlignment(DataGridViewContentAlignment align)
{
if ((align & anyRight) != 0)
{
return HorizontalAlignment.Right;
}
else if ((align & anyCenter) != 0)
{
if ((align & anyCenter) != 0)
return HorizontalAlignment.Center;
}
else
{
return HorizontalAlignment.Left;
}
}
}
}

View File

@ -21,21 +21,17 @@ namespace GradeCalc
/// <summary>
/// Represents the implicit cell that gets cloned when adding rows to the grid.
/// </summary>
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override DataGridViewCell CellTemplate
{
get {
return base.CellTemplate;
}
set {
get => base.CellTemplate;
set
{
DataGridViewNumericUpDownCell dataGridViewNumericUpDownCell = value as DataGridViewNumericUpDownCell;
if (value != null && dataGridViewNumericUpDownCell == null)
{
throw new InvalidCastException("Value provided for CellTemplate must be of type DataGridViewNumericUpDownElements.DataGridViewNumericUpDownCell or derive from it.");
}
throw new InvalidCastException(
"Value provided for CellTemplate must be of type DataGridViewNumericUpDownElements.DataGridViewNumericUpDownCell or derive from it.");
base.CellTemplate = value;
}
}
@ -43,25 +39,23 @@ namespace GradeCalc
/// <summary>
/// Replicates the DecimalPlaces property of the DataGridViewNumericUpDownCell cell type.
/// </summary>
[
Category("Appearance"),
DefaultValue(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultDecimalPlaces),
Description("Indicates the number of decimal places to display.")
]
[Category("Appearance")]
[DefaultValue(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultDecimalPlaces)]
[Description("Indicates the number of decimal places to display.")]
public int DecimalPlaces
{
get {
if (NumericUpDownCellTemplate == null)
get
{
throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
}
if (NumericUpDownCellTemplate == null)
throw new InvalidOperationException(
"Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
return NumericUpDownCellTemplate.DecimalPlaces;
}
set {
if (NumericUpDownCellTemplate == null)
set
{
throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
}
if (NumericUpDownCellTemplate == null)
throw new InvalidOperationException(
"Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
// Update the template cell so that subsequent cloned cells use the new value.
NumericUpDownCellTemplate.DecimalPlaces = value;
if (DataGridView != null)
@ -74,14 +68,13 @@ namespace GradeCalc
// Be careful not to unshare rows unnecessarily.
// This could have severe performance repercussions.
DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
DataGridViewNumericUpDownCell dataGridViewCell = dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
DataGridViewNumericUpDownCell dataGridViewCell =
dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null)
{
// Call the internal SetDecimalPlaces method instead of the property to avoid invalidation
// of each cell. The whole column is invalidated later in a single operation for better performance.
dataGridViewCell.SetDecimalPlaces(rowIndex, value);
}
}
DataGridView.InvalidateColumn(Index);
// TODO: Call the grid's autosizing methods to autosize the column, rows, column headers / row headers as needed.
}
@ -91,24 +84,22 @@ namespace GradeCalc
/// <summary>
/// Replicates the Increment property of the DataGridViewNumericUpDownCell cell type.
/// </summary>
[
Category("Data"),
Description("Indicates the amount to increment or decrement on each button click.")
]
[Category("Data")]
[Description("Indicates the amount to increment or decrement on each button click.")]
public decimal Increment
{
get {
if (NumericUpDownCellTemplate == null)
get
{
throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
}
if (NumericUpDownCellTemplate == null)
throw new InvalidOperationException(
"Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
return NumericUpDownCellTemplate.Increment;
}
set {
if (NumericUpDownCellTemplate == null)
set
{
throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
}
if (NumericUpDownCellTemplate == null)
throw new InvalidOperationException(
"Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
NumericUpDownCellTemplate.Increment = value;
if (DataGridView != null)
{
@ -117,44 +108,34 @@ namespace GradeCalc
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
{
DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
DataGridViewNumericUpDownCell dataGridViewCell = dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null)
{
dataGridViewCell.SetIncrement(rowIndex, value);
DataGridViewNumericUpDownCell dataGridViewCell =
dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null) dataGridViewCell.SetIncrement(rowIndex, value);
}
}
}
}
}
/// Indicates whether the Increment property should be persisted.
private bool ShouldSerializeIncrement()
{
return !Increment.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultIncrement);
}
/// <summary>
/// Replicates the Maximum property of the DataGridViewNumericUpDownCell cell type.
/// </summary>
[
Category("Data"),
Description("Indicates the maximum value for the numeric up-down cells."),
RefreshProperties(RefreshProperties.All)
]
[Category("Data")]
[Description("Indicates the maximum value for the numeric up-down cells.")]
[RefreshProperties(RefreshProperties.All)]
public decimal Maximum
{
get {
if (NumericUpDownCellTemplate == null)
get
{
throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
}
if (NumericUpDownCellTemplate == null)
throw new InvalidOperationException(
"Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
return NumericUpDownCellTemplate.Maximum;
}
set {
if (NumericUpDownCellTemplate == null)
set
{
throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
}
if (NumericUpDownCellTemplate == null)
throw new InvalidOperationException(
"Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
NumericUpDownCellTemplate.Maximum = value;
if (DataGridView != null)
{
@ -163,11 +144,9 @@ namespace GradeCalc
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
{
DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
DataGridViewNumericUpDownCell dataGridViewCell = dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null)
{
dataGridViewCell.SetMaximum(rowIndex, value);
}
DataGridViewNumericUpDownCell dataGridViewCell =
dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null) dataGridViewCell.SetMaximum(rowIndex, value);
}
DataGridView.InvalidateColumn(Index);
// TODO: This column and/or grid rows may need to be autosized depending on their
@ -177,34 +156,26 @@ namespace GradeCalc
}
}
/// Indicates whether the Maximum property should be persisted.
private bool ShouldSerializeMaximum()
{
return !Maximum.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMaximum);
}
/// <summary>
/// Replicates the Minimum property of the DataGridViewNumericUpDownCell cell type.
/// </summary>
[
Category("Data"),
Description("Indicates the minimum value for the numeric up-down cells."),
RefreshProperties(RefreshProperties.All)
]
[Category("Data")]
[Description("Indicates the minimum value for the numeric up-down cells.")]
[RefreshProperties(RefreshProperties.All)]
public decimal Minimum
{
get {
if (NumericUpDownCellTemplate == null)
get
{
throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
}
if (NumericUpDownCellTemplate == null)
throw new InvalidOperationException(
"Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
return NumericUpDownCellTemplate.Minimum;
}
set {
if (NumericUpDownCellTemplate == null)
set
{
throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
}
if (NumericUpDownCellTemplate == null)
throw new InvalidOperationException(
"Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
NumericUpDownCellTemplate.Minimum = value;
if (DataGridView != null)
{
@ -213,11 +184,9 @@ namespace GradeCalc
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
{
DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
DataGridViewNumericUpDownCell dataGridViewCell = dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null)
{
dataGridViewCell.SetMinimum(rowIndex, value);
}
DataGridViewNumericUpDownCell dataGridViewCell =
dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null) dataGridViewCell.SetMinimum(rowIndex, value);
}
DataGridView.InvalidateColumn(Index);
// TODO: This column and/or grid rows may need to be autosized depending on their
@ -227,34 +196,26 @@ namespace GradeCalc
}
}
/// Indicates whether the Maximum property should be persisted.
private bool ShouldSerializeMinimum()
{
return !Minimum.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMinimum);
}
/// <summary>
/// Replicates the ThousandsSeparator property of the DataGridViewNumericUpDownCell cell type.
/// </summary>
[
Category("Data"),
DefaultValue(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultThousandsSeparator),
Description("Indicates whether the thousands separator will be inserted between every three decimal digits.")
]
[Category("Data")]
[DefaultValue(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultThousandsSeparator)]
[Description("Indicates whether the thousands separator will be inserted between every three decimal digits.")]
public bool ThousandsSeparator
{
get {
if (NumericUpDownCellTemplate == null)
get
{
throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
}
if (NumericUpDownCellTemplate == null)
throw new InvalidOperationException(
"Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
return NumericUpDownCellTemplate.ThousandsSeparator;
}
set {
if (NumericUpDownCellTemplate == null)
set
{
throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
}
if (NumericUpDownCellTemplate == null)
throw new InvalidOperationException(
"Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
NumericUpDownCellTemplate.ThousandsSeparator = value;
if (DataGridView != null)
{
@ -263,11 +224,9 @@ namespace GradeCalc
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
{
DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
DataGridViewNumericUpDownCell dataGridViewCell = dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null)
{
dataGridViewCell.SetThousandsSeparator(rowIndex, value);
}
DataGridViewNumericUpDownCell dataGridViewCell =
dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null) dataGridViewCell.SetThousandsSeparator(rowIndex, value);
}
DataGridView.InvalidateColumn(Index);
// TODO: This column and/or grid rows may need to be autosized depending on their
@ -280,12 +239,19 @@ namespace GradeCalc
/// <summary>
/// Small utility function that returns the template cell as a DataGridViewNumericUpDownCell
/// </summary>
private DataGridViewNumericUpDownCell NumericUpDownCellTemplate
{
get {
return (DataGridViewNumericUpDownCell)CellTemplate;
}
}
private DataGridViewNumericUpDownCell NumericUpDownCellTemplate => (DataGridViewNumericUpDownCell) CellTemplate;
/// Indicates whether the Increment property should be persisted.
private bool ShouldSerializeIncrement() =>
!Increment.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultIncrement);
/// Indicates whether the Maximum property should be persisted.
private bool ShouldSerializeMaximum() =>
!Maximum.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMaximum);
/// Indicates whether the Maximum property should be persisted.
private bool ShouldSerializeMinimum() =>
!Minimum.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMinimum);
/// <summary>
/// Returns a standard compact string representation of the column.

View File

@ -1,5 +1,7 @@
using System;
using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace GradeCalc
@ -9,27 +11,19 @@ namespace GradeCalc
/// </summary>
internal class DataGridViewNumericUpDownEditingControl : NumericUpDown, IDataGridViewEditingControl
{
// Needed to forward keyboard messages to the child TextBox control.
[System.Runtime.InteropServices.DllImport("USER32.DLL", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
// The grid that owns this editing control
private DataGridView dataGridView;
// Stores the row index in which the editing control resides
// Stores whether the editing control's value has changed or not
private bool valueChanged;
// Stores the row index in which the editing control resides
private int rowIndex;
/// <summary>
/// Constructor of the editing control class
/// </summary>
public DataGridViewNumericUpDownEditingControl()
{
// The editing control must not be part of the tabbing loop
TabStop = false;
}
public DataGridViewNumericUpDownEditingControl() => TabStop = false;
// Beginning of the IDataGridViewEditingControl interface implementation
@ -38,12 +32,8 @@ namespace GradeCalc
/// </summary>
public virtual DataGridView EditingControlDataGridView
{
get {
return dataGridView;
}
set {
dataGridView = value;
}
get => dataGridView;
set => dataGridView = value;
}
/// <summary>
@ -51,61 +41,35 @@ namespace GradeCalc
/// </summary>
public virtual object EditingControlFormattedValue
{
get {
return GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting);
}
set {
Text = (string)value;
}
get => GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting);
set => Text = (string) value;
}
/// <summary>
/// Property which represents the row in which the editing control resides
/// </summary>
public virtual int EditingControlRowIndex
{
get {
return rowIndex;
}
set {
rowIndex = value;
}
}
public virtual int EditingControlRowIndex { get; set; }
/// <summary>
/// Property which indicates whether the value of the editing control has changed or not
/// </summary>
public virtual bool EditingControlValueChanged
{
get {
return valueChanged;
}
set {
valueChanged = value;
}
get => valueChanged;
set => valueChanged = value;
}
/// <summary>
/// Property which determines which cursor must be used for the editing panel,
/// i.e. the parent of the editing control.
/// </summary>
public virtual Cursor EditingPanelCursor
{
get {
return Cursors.Default;
}
}
public virtual Cursor EditingPanelCursor => Cursors.Default;
/// <summary>
/// Property which indicates whether the editing control needs to be repositioned
/// when its value changes.
/// </summary>
public virtual bool RepositionEditingControlOnValueChange
{
get {
return false;
}
}
public virtual bool RepositionEditingControlOnValueChange => false;
/// <summary>
/// Method called by the grid before the editing control is shown so it can adapt to the
@ -141,15 +105,13 @@ namespace GradeCalc
{
TextBox textBox = Controls[1] as TextBox;
if (textBox != null)
{
// If the end of the selection is at the end of the string,
// let the DataGridView treat the key message
if (RightToLeft == RightToLeft.No && !(textBox.SelectionLength == 0 && textBox.SelectionStart == textBox.Text.Length) ||
RightToLeft == RightToLeft.Yes && !(textBox.SelectionLength == 0 && textBox.SelectionStart == 0))
{
if ((RightToLeft == RightToLeft.No &&
!(textBox.SelectionLength == 0 && textBox.SelectionStart == textBox.Text.Length)) ||
(RightToLeft == RightToLeft.Yes &&
!(textBox.SelectionLength == 0 && textBox.SelectionStart == 0)))
return true;
}
}
break;
}
@ -157,35 +119,27 @@ namespace GradeCalc
{
TextBox textBox = Controls[1] as TextBox;
if (textBox != null)
{
// If the end of the selection is at the begining of the string
// or if the entire text is selected and we did not start editing,
// send this character to the dataGridView, else process the key message
if (RightToLeft == RightToLeft.No && !(textBox.SelectionLength == 0 && textBox.SelectionStart == 0) ||
RightToLeft == RightToLeft.Yes && !(textBox.SelectionLength == 0 && textBox.SelectionStart == textBox.Text.Length))
{
if ((RightToLeft == RightToLeft.No &&
!(textBox.SelectionLength == 0 && textBox.SelectionStart == 0)) ||
(RightToLeft == RightToLeft.Yes &&
!(textBox.SelectionLength == 0 && textBox.SelectionStart == textBox.Text.Length)))
return true;
}
}
break;
}
case Keys.Down:
// If the current value hasn't reached its minimum yet, handle the key. Otherwise let
// the grid handle it.
if (Value > Minimum)
{
return true;
}
if (Value > Minimum) return true;
break;
case Keys.Up:
// If the current value hasn't reached its maximum yet, handle the key. Otherwise let
// the grid handle it.
if (Value < Maximum)
{
return true;
}
if (Value < Maximum) return true;
break;
case Keys.Home:
@ -194,12 +148,8 @@ namespace GradeCalc
// Let the grid handle the key if the entire text is selected.
TextBox textBox = Controls[1] as TextBox;
if (textBox != null)
{
if (textBox.SelectionLength != textBox.Text.Length)
{
return true;
}
}
break;
}
@ -208,13 +158,9 @@ namespace GradeCalc
// Let the grid handle the key if the carret is at the end of the text.
TextBox textBox = Controls[1] as TextBox;
if (textBox != null)
{
if (textBox.SelectionLength > 0 ||
textBox.SelectionStart < textBox.Text.Length)
{
return true;
}
}
break;
}
}
@ -231,7 +177,7 @@ namespace GradeCalc
{
// Prevent the Value from being set to Maximum or Minimum when the cell is being painted.
UserEdit = (context & DataGridViewDataErrorContexts.Display) == 0;
return Value.ToString((ThousandsSeparator ? "N" : "F") + DecimalPlaces.ToString());
return Value.ToString((ThousandsSeparator ? "N" : "F") + DecimalPlaces);
}
finally
{
@ -249,17 +195,17 @@ namespace GradeCalc
if (textBox != null)
{
if (selectAll)
{
textBox.SelectAll();
}
else
{
// Do not select all the text, but
// position the caret at the end of the text
textBox.SelectionStart = textBox.Text.Length;
}
}
}
// Needed to forward keyboard messages to the child TextBox control.
[DllImport("USER32.DLL", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
// End of the IDataGridViewEditingControl interface implementation
@ -293,30 +239,22 @@ namespace GradeCalc
}
else
{
System.Globalization.NumberFormatInfo numberFormatInfo = System.Globalization.CultureInfo.CurrentCulture.NumberFormat;
NumberFormatInfo numberFormatInfo = CultureInfo.CurrentCulture.NumberFormat;
string decimalSeparatorStr = numberFormatInfo.NumberDecimalSeparator;
string groupSeparatorStr = numberFormatInfo.NumberGroupSeparator;
string negativeSignStr = numberFormatInfo.NegativeSign;
if (!string.IsNullOrEmpty(decimalSeparatorStr) && decimalSeparatorStr.Length == 1)
{
notifyValueChange = decimalSeparatorStr[0] == e.KeyChar;
}
if (!notifyValueChange && !string.IsNullOrEmpty(groupSeparatorStr) && groupSeparatorStr.Length == 1)
{
notifyValueChange = groupSeparatorStr[0] == e.KeyChar;
}
if (!notifyValueChange && !string.IsNullOrEmpty(negativeSignStr) && negativeSignStr.Length == 1)
{
notifyValueChange = negativeSignStr[0] == e.KeyChar;
}
}
if (notifyValueChange)
{
// Let the DataGridView know about the value change
NotifyDataGridViewOfValueChange();
}
}
/// <summary>
/// Listen to the ValueChanged notification to forward the change to the grid.
@ -325,11 +263,9 @@ namespace GradeCalc
{
base.OnValueChanged(e);
if (Focused)
{
// Let the DataGridView know about the value change
NotifyDataGridViewOfValueChange();
}
}
/// <summary>
/// A few keyboard messages need to be forwarded to the inner textbox of the
@ -343,10 +279,7 @@ namespace GradeCalc
SendMessage(textBox.Handle, m.Msg, m.WParam, m.LParam);
return true;
}
else
{
return base.ProcessKeyEventArgs(ref m);
}
}
}
}

View File

@ -58,8 +58,9 @@
<Reference Include="Antlr4.Runtime, Version=4.6.0.0, Culture=neutral, PublicKeyToken=09abb75b9ed49849, processorArchitecture=MSIL">
<HintPath>..\packages\Antlr4.Runtime.4.6.6\lib\net45\Antlr4.Runtime.dll</HintPath>
</Reference>
<Reference Include="EPPlus, Version=4.5.3.2, Culture=neutral, PublicKeyToken=ea159fdaa78159a1, processorArchitecture=MSIL">
<HintPath>..\packages\EPPlus.4.5.3.2\lib\net40\EPPlus.dll</HintPath>
<Reference Include="EPPlus, Version=4.5.3.3, Culture=neutral, PublicKeyToken=ea159fdaa78159a1">
<HintPath>..\packages\EPPlus.4.5.3.3\lib\net40\EPPlus.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NCalc2, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NCalc2.2.1.0\lib\net46\NCalc2.dll</HintPath>

View File

@ -1,21 +1,23 @@
using NCalc2;
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using NCalc2;
using OfficeOpenXml;
using System.IO;
using System.Drawing;
using OfficeOpenXml.Style;
namespace GradeCalc
{
public partial class MainForm : Form
{
private List<DataGridViewNumericUpDownColumn> taskColumns = new List<DataGridViewNumericUpDownColumn>();
private DataGridViewTextBoxColumn nameColumn;
private DataGridViewTextBoxColumn gradeColumn;
private readonly DataGridViewTextBoxColumn gradeColumn;
private readonly DataGridViewTextBoxColumn nameColumn;
private readonly List<DataGridViewNumericUpDownColumn>
taskColumns = new List<DataGridViewNumericUpDownColumn>();
public MainForm()
{
@ -32,8 +34,10 @@ namespace GradeCalc
tasksNum_ValueChanged(null, null);
}
int round(double val) => (int)Math.Round(val);
Color getColor(double x, double max) => Color.FromArgb(round(255 * (1 - (x / max))), round(255 * (x / max)), 0);
private int round(double val) => (int) Math.Round(val);
private Color getColor(double x, double max) =>
Color.FromArgb(round(255 * (1 - (x / max))), round(255 * (x / max)), 0);
private void calcButton_Click(object sender, EventArgs e)
{
@ -61,7 +65,8 @@ namespace GradeCalc
ex.Parameters["score"] = (double) totalScore;
ex.Parameters["maxScore"] = (double) maxScore;
double grade = 6 - (NCalcDoubleParser.Parse(ex.Evaluate()) * 5);
gradeCell.Value = (grade.ToString().Length > 13 ? grade.ToString().Remove(13) : grade.ToString()) + " " + texGrade(grade);
gradeCell.Value = (grade.ToString().Length > 13 ? grade.ToString().Remove(13) : grade.ToString()) +
" " + texGrade(grade);
gradeCell.Style.BackColor = getColor(grade - 1, 5);
}
catch (Exception e1)
@ -86,7 +91,7 @@ namespace GradeCalc
DataGridViewNumericUpDownColumn clm = new DataGridViewNumericUpDownColumn();
clm.Minimum = 0;
clm.Maximum = 10;
clm.Name = "Task " + (taskColumns.Count + 1).ToString();
clm.Name = "Task " + (taskColumns.Count + 1);
dataGridView.Columns.Add(clm);
taskColumns.Add(clm);
}
@ -95,8 +100,9 @@ namespace GradeCalc
private string texGrade(double g)
{
double gGrade = (new double[] { -0.5, 0, 0.5 }).OrderBy(x => Math.Abs(x - (g - round(g)) + 1)).First();
return ((char)('A' + round(g) - 1)).ToString() + ((g == 1 || gGrade == -0.5) ? "+" : (g == 6 || gGrade == 0.5) ? "-" : "");
double gGrade = new[] {-0.5, 0, 0.5}.OrderBy(x => Math.Abs((x - (g - round(g))) + 1)).First();
return (char) (('A' + round(g)) - 1) +
(g == 1 || gGrade == -0.5 ? "+" : g == 6 || gGrade == 0.5 ? "-" : "");
}
private void saveButton_Click(object sender, EventArgs e)
@ -106,11 +112,10 @@ namespace GradeCalc
Filter = "Excel Spreadsheet|*.xlst"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
using (ExcelPackage excel = new ExcelPackage())
{
ExcelWorksheet worksheet = excel.Workbook.Worksheets.Add("Worksheet1");
List<string[]> headerRow = new List<string[]>()
List<string[]> headerRow = new List<string[]>
{
dataGridView.Columns.OfType<DataGridViewColumn>().Select(s => s.HeaderText).ToArray()
};
@ -130,8 +135,10 @@ namespace GradeCalc
foreach (DataGridViewCell cell in s.Cells)
{
worksheet.Cells[cell.RowIndex + 2, cell.ColumnIndex + 1].Value = cell.Value.ToString();
worksheet.Cells[cell.RowIndex + 2, cell.ColumnIndex + 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[cell.RowIndex + 2, cell.ColumnIndex + 1].Style.Fill.BackgroundColor.SetColor(cell.Style.BackColor);
worksheet.Cells[cell.RowIndex + 2, cell.ColumnIndex + 1].Style.Fill.PatternType =
ExcelFillStyle.Solid;
worksheet.Cells[cell.RowIndex + 2, cell.ColumnIndex + 1].Style.Fill.BackgroundColor
.SetColor(cell.Style.BackColor);
}
});
excel.SaveAs(new FileInfo(dialog.FileName));
@ -139,4 +146,3 @@ namespace GradeCalc
}
}
}
}

View File

@ -1,40 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GradeCalc
{
static class NCalcDoubleParser
internal static class NCalcDoubleParser
{
public static double Parse(object NCalcOutput)
{
if (NCalcOutput.GetType() == typeof(bool))
return (bool) NCalcOutput ? 1 : 0;
else if (NCalcOutput.GetType() == typeof(byte))
if (NCalcOutput.GetType() == typeof(byte))
return (byte) NCalcOutput;
else if (NCalcOutput.GetType() == typeof(sbyte))
if (NCalcOutput.GetType() == typeof(sbyte))
return (sbyte) NCalcOutput;
else if (NCalcOutput.GetType() == typeof(short))
if (NCalcOutput.GetType() == typeof(short))
return (short) NCalcOutput;
else if (NCalcOutput.GetType() == typeof(ushort))
if (NCalcOutput.GetType() == typeof(ushort))
return (ushort) NCalcOutput;
else if (NCalcOutput.GetType() == typeof(int))
if (NCalcOutput.GetType() == typeof(int))
return (int) NCalcOutput;
else if (NCalcOutput.GetType() == typeof(uint))
if (NCalcOutput.GetType() == typeof(uint))
return (uint) NCalcOutput;
else if (NCalcOutput.GetType() == typeof(long))
if (NCalcOutput.GetType() == typeof(long))
return (long) NCalcOutput;
else if (NCalcOutput.GetType() == typeof(ulong))
if (NCalcOutput.GetType() == typeof(ulong))
return (ulong) NCalcOutput;
else if (NCalcOutput.GetType() == typeof(float))
if (NCalcOutput.GetType() == typeof(float))
return (float) NCalcOutput;
else if (NCalcOutput.GetType() == typeof(double))
if (NCalcOutput.GetType() == typeof(double))
return (double) NCalcOutput;
else if (NCalcOutput.GetType() == typeof(decimal))
if (NCalcOutput.GetType() == typeof(decimal))
return (double) (decimal) NCalcOutput;
throw new ArgumentException("Type mismatch! (" + NCalcOutput.GetType().ToString() + ")");
throw new ArgumentException("Type mismatch! (" + NCalcOutput.GetType() + ")");
}
}
}

View File

@ -3,7 +3,7 @@
<package id="Antlr4" version="4.6.6" targetFramework="net461" developmentDependency="true" />
<package id="Antlr4.CodeGenerator" version="4.6.6" targetFramework="net461" developmentDependency="true" />
<package id="Antlr4.Runtime" version="4.6.6" targetFramework="net461" />
<package id="EPPlus" version="4.5.3.2" targetFramework="net461" />
<package id="EPPlus" version="4.5.3.3" targetFramework="net461" />
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net461" />
<package id="NCalc2" version="2.1.0" targetFramework="net48" />
<package id="System.Dynamic.Runtime" version="4.3.0" targetFramework="net48" />