How to update items in a datagridview with BindingList?

Sn0wb0y
Sn0wb0y used Ask the Experts™
on
In my windows forms application, I have a list of items <Container> which are populated into a datagridview. Each container has a unique ID. As follows:

ui1
In the datagridview, I have a "Modify" button column that when clicked, transfers the properties of the selected container onto the textbox controls in my UI. As follows:

ui2
Question: Given the above, how do I update the properties of a container within my list?

Background code:

Container class:

public class Container
    {
        #region Properties

        // Unique container ID
        public string ContainerID { get; set; }
        // Container description
        public string Description { get; set; }
        // Container payload capacity - weight
        public double CapacityWeight { get; set; }
        // Container payload capacity - cube
        public double CapacityCube { get; set; }
        
        #endregion  

        #region Constructor

        // Default constructor
        public Container()
        {
            ContainerID = Extension.NewID();
        }

        #endregion
    }

Open in new window


List initialization:

// Create an initial arbitrary list of containers to choose from
BindingList<Container> Containers = new BindingList<Container>();

Open in new window


private void initContainers()
        {
            // Add some containers to the container list
            Containers.Add(new Container() { Description = "20FT GENERAL PURPOSE", CapacityWeight = 23.4, CapacityCube = 30 });
            Containers.Add(new Container() { Description = "40FT GENERAL PURPOSE", CapacityWeight = 24.5, CapacityCube = 60 });
            Containers.Add(new Container() { Description = "40FT GENERAL PURPOSE - HIGH CUBE", CapacityWeight = 25.0, CapacityCube = 70 });
            Containers.Add(new Container() { Description = "US CHEP TWO-WAY PALLET", CapacityWeight = 1.524, CapacityCube = 1.8 });
        }

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Like this:

Form1.cs -
using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;

namespace EE_Q29157886
{
	public partial class Form1 : Form
	{
		BindingList<Container> containers = new BindingList<Container>();

		public Form1()
		{
			InitializeComponent();
		}

		private void OnLoad(object sender, EventArgs e)
		{
			containers.Add(new Container() { ContainerID = 1, Description = "20FT GENERAL PURPOSE", CapacityWeight = 23.4, CapacityCube = 30 });
			containers.Add(new Container() { ContainerID = 2, Description = "40FT GENERAL PURPOSE", CapacityWeight = 24.5, CapacityCube = 60 });
			containers.Add(new Container() { ContainerID = 3, Description = "40FT GENERAL PURPOSE - HIGH CUBE", CapacityWeight = 25.0, CapacityCube = 70 });
			containers.Add(new Container() { ContainerID = 4, Description = "US CHEP TWO-WAY PALLET", CapacityWeight = 1.524, CapacityCube = 1.8 });

			bindingSource1.DataSource = containers;
			dataGridView1.DataSource = bindingSource1;
		}

		private void OnClick(object sender, EventArgs e)
		{
			if (sender is ToolStripMenuItem)
			{
				var mnu = sender as ToolStripMenuItem;
				if (mnu.Equals(modifyToolStripMenuItem))
				{
					var container = dataGridView1?.SelectedRows?.Cast<DataGridViewRow>()?.First()?.DataBoundItem as Container;
					if (container == default(Container))
					{
						container = new Container() { ContainerID = containers.Max(c => c.ContainerID) + 1 };
					}
					var editor = new DynamicForm<Container>("Modify Container", container);
					editor.ShowDialog();
					dataGridView1.Refresh();
				}
				else if (mnu.Equals(addToolStripMenuItem))
				{
					var container = new Container() { ContainerID = containers.Max(c => c.ContainerID) + 1 };
					var editor = new DynamicForm<Container>("Add Container", container);
					if (editor.ShowDialog() == DialogResult.OK)
					{
						containers.Add(container);
					}
					dataGridView1.Refresh();
				}
				else if (mnu.Equals(removeToolStripMenuItem))
				{
					var container = dataGridView1?.SelectedRows?.Cast<DataGridViewRow>()?.First()?.DataBoundItem as Container;
					if (container != default(Container))
					{
						containers.Remove(container);
					}
					dataGridView1.Refresh();
				}
			}
		}

		private void OnRowContextMenuStripNeeded(object sender, DataGridViewRowContextMenuStripNeededEventArgs e)
		{
			if (sender is DataGridView)
			{
				var grid = sender as DataGridView;
				if (!grid.SelectedRows.Contains(grid.Rows[e.RowIndex]))
					grid.Rows[e.RowIndex].Selected = true;
				e.ContextMenuStrip = contextMenuStrip1;
			}
		}
	}
}

Open in new window

Form1.Designer.cs -
namespace EE_Q29157886
{
	partial class Form1
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.dataGridView1 = new System.Windows.Forms.DataGridView();
			this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
			this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
			this.modifyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
			this.addToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
			this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
			((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).BeginInit();
			this.contextMenuStrip1.SuspendLayout();
			this.SuspendLayout();
			// 
			// dataGridView1
			// 
			this.dataGridView1.AllowUserToAddRows = false;
			this.dataGridView1.AllowUserToDeleteRows = false;
			this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
			this.dataGridView1.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells;
			this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
			this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
			this.dataGridView1.Location = new System.Drawing.Point(0, 0);
			this.dataGridView1.MultiSelect = false;
			this.dataGridView1.Name = "dataGridView1";
			this.dataGridView1.ReadOnly = true;
			this.dataGridView1.RowHeadersVisible = false;
			this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
			this.dataGridView1.Size = new System.Drawing.Size(516, 223);
			this.dataGridView1.TabIndex = 0;
			this.dataGridView1.RowContextMenuStripNeeded += new System.Windows.Forms.DataGridViewRowContextMenuStripNeededEventHandler(this.OnRowContextMenuStripNeeded);
			// 
			// contextMenuStrip1
			// 
			this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.modifyToolStripMenuItem,
            this.addToolStripMenuItem,
            this.removeToolStripMenuItem});
			this.contextMenuStrip1.Name = "contextMenuStrip1";
			this.contextMenuStrip1.Size = new System.Drawing.Size(181, 92);
			// 
			// modifyToolStripMenuItem
			// 
			this.modifyToolStripMenuItem.Name = "modifyToolStripMenuItem";
			this.modifyToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
			this.modifyToolStripMenuItem.Text = "Modify";
			this.modifyToolStripMenuItem.Click += new System.EventHandler(this.OnClick);
			// 
			// addToolStripMenuItem
			// 
			this.addToolStripMenuItem.Name = "addToolStripMenuItem";
			this.addToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
			this.addToolStripMenuItem.Text = "Add";
			this.addToolStripMenuItem.Click += new System.EventHandler(this.OnClick);
			// 
			// removeToolStripMenuItem
			// 
			this.removeToolStripMenuItem.Name = "removeToolStripMenuItem";
			this.removeToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
			this.removeToolStripMenuItem.Text = "Remove";
			this.removeToolStripMenuItem.Click += new System.EventHandler(this.OnClick);
			// 
			// Form1
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(516, 223);
			this.Controls.Add(this.dataGridView1);
			this.Name = "Form1";
			this.Text = "Form1";
			this.Load += new System.EventHandler(this.OnLoad);
			((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).EndInit();
			this.contextMenuStrip1.ResumeLayout(false);
			this.ResumeLayout(false);

		}

		#endregion

		private System.Windows.Forms.DataGridView dataGridView1;
		private System.Windows.Forms.BindingSource bindingSource1;
		private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
		private System.Windows.Forms.ToolStripMenuItem modifyToolStripMenuItem;
		private System.Windows.Forms.ToolStripMenuItem addToolStripMenuItem;
		private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem;
	}
}

Open in new window

DynamicForm.cs -
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Forms;

namespace EE_Q29157886
{
	public partial class DynamicForm<T> : Form
	{
		List<Control> controls;
		public T DataItem { get; private set; }

		public DynamicForm(string title, T item)
		{
			InitializeComponent();
			InitializeForm(title);
			InitializeControls(item);
			DataItem = item;

			// We need to ensure that the required fields are clearly marked, so that
			// the user can see which controls they must complete in order for the OK
			// button to become enabled.
			ValidateControls();
		}

		private void InitializeForm(string title)
		{
			Text = title;
			MaximizeBox = false;
			MinimizeBox = false;
			ShowIcon = false;
			ShowInTaskbar = false;
			FormBorderStyle = FormBorderStyle.FixedDialog;
			StartPosition = FormStartPosition.CenterParent;
			errorProvider.BlinkStyle = ErrorBlinkStyle.NeverBlink;
			controls = new List<Control>();
		}

		private void InitializeControls(T item)
		{
			PropertyInfo[] properties = item.GetType().GetProperties();

			// Create layout table
			tableLayoutPanel1.RowCount = properties.Length;

			// For each property
			int rowNumber = 0;
			foreach (var property in properties)
			{
				Control ctrl = ControlFactory<T>.CreateControl(item, property);
				if (ctrl != null)
				{
					// Get custom attributes
					object[] attributes = property.GetCustomAttributes(true);
					ctrl = ApplyAttributes(ctrl, attributes);

					// Disable the control if property read only
					if (!property.CanWrite)
					{
						ctrl.Enabled = false;
					}

					// Build label
					if (ctrl.Visible)
					{
						ControlTag tag = (ControlTag)ctrl.Tag;
						Label label = ControlFactory<T>.CreateLabel(property.Name);
						if (!string.IsNullOrEmpty(tag.CustomLabel))
						{
							label.Text = tag.CustomLabel;
						}
						tableLayoutPanel1.Controls.Add(label, 0, rowNumber);
						tableLayoutPanel1.Controls.Add(ctrl, 1, rowNumber);
						controls.Add(ctrl);
					}
				}
				rowNumber++;
			}

			// Resize the form
			Width = tableLayoutPanel1.Width + 40;
			Height = tableLayoutPanel1.Height + 90;
		}

		/// <summary>
		/// Applies the settings from the custom attributes to the control.
		/// </summary>
		/// <param name="ctrl">A control bound to property</param>
		/// <param name="attributes">Custom attributes for the property</param>
		/// <returns></returns>
		private Control ApplyAttributes(Control ctrl, object[] attributes)
		{
			ControlTag tag = (ControlTag)ctrl.Tag;
			NumericSettingsAttribute attrRange = null;
			DisplaySettingsAttribute attrDisplay = null;
			RequiredFieldAttribute attrRequired = null;
			foreach (object attribute in attributes)
			{
				if (attribute is NumericSettingsAttribute)
				{
					attrRange = (NumericSettingsAttribute)attribute;
				}
				else if (attribute is DisplaySettingsAttribute)
				{
					attrDisplay = (DisplaySettingsAttribute)attribute;
				}
				else if (attribute is RequiredFieldAttribute)
				{
					attrRequired = (RequiredFieldAttribute)attribute;
				}
			}

			// Attach LostFocus handler for input validation
			ctrl.LostFocus += OnLostFocus;

			// Display Attribute
			if (attrDisplay != null)
			{
				tag.CustomLabel = attrDisplay.Label;
				ctrl.Enabled = !attrDisplay.ReadOnly;
				ctrl.Visible = attrDisplay.Visible;
				if (attrDisplay.Width > 0)
				{
					ctrl.Width = attrDisplay.Width;
				}

				if (!string.IsNullOrWhiteSpace(attrDisplay.Description))
				{
					toolTip.SetToolTip(ctrl, attrDisplay.Description);
				}
			}

			// Required Field Attribute
			if (attrRequired != null)
			{
				tag.ErrorMessage = string.IsNullOrEmpty(attrRequired.Message) ? "Required" : attrRequired.Message;
			}
			return ctrl;
		}

		private void OnLostFocus(object sender, EventArgs e)
		{
			ValidateControls();
		}

		private void OnClick(object sender, EventArgs e)
		{
			SaveControlValues();
		}

		private bool ValidateControl(Control control)
		{
			bool isValid = true;

			// Validation currently limited to TextBoxes only
			TextBox txt = control as TextBox;
			if (txt != null)
			{
				// If the textbox is empty, show a warning
				ControlTag tag = (ControlTag)txt.Tag;
				if (tag.IsRequired && string.IsNullOrEmpty(txt.Text))
				{
					errorProvider.SetError(txt, tag.ErrorMessage);
					isValid = false;
				}
				else
				{
					errorProvider.SetError(txt, string.Empty);
				}
			}
			return isValid;
		}

		/// <summary>
		/// Returns false if any controls are invalid.
		/// </summary>
		/// <returns></returns>
		private void ValidateControls()
		{
			bool isValid = true;
			foreach (Control control in controls)
			{
				if (!ValidateControl(control))
				{
					isValid = false;
				}
			}
			btnOk.Enabled = isValid;
		}

		/// <summary>
		/// Saves the controls value back to the data object.
		/// </summary>
		private void SaveControlValues()
		{
			// For each TextBox, Dropdown etc...
			foreach (Control c in controls)
			{
				ControlTag tag = (ControlTag)c.Tag;
				PropertyInfo property = DataItem.GetType().GetProperty(tag.PropertyName);
				Type type = property.PropertyType;
				if (c is TextBox)
				{
					TextBox textbox = (TextBox)c;
					property.SetValue(DataItem, Convert.ChangeType(textbox.Text, type), null);
				}
				else if (c is NumericUpDown)
				{
					NumericUpDown numeric = (NumericUpDown)c;
					property.SetValue(DataItem, Convert.ChangeType(numeric.Value, type), null);
				}
				else if (c is CheckBox)
				{
					CheckBox checkbox = c as CheckBox;
					property.SetValue(DataItem, checkbox.Checked, null);
				}
				else if (c is ComboBox)
				{
					ComboBox dropdown = c as ComboBox;
					property.SetValue(DataItem, Enum.Parse(tag.PropertyType, Convert.ToString(dropdown.SelectedItem)), null);
				}
			}
		}
	}
}

Open in new window

DynamicForm.Designer.cs -
namespace EE_Q29157886
{
	partial class DynamicForm<T>
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.btnCancel = new System.Windows.Forms.Button();
			this.btnOk = new System.Windows.Forms.Button();
			this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
			this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
			this.toolTip = new System.Windows.Forms.ToolTip(this.components);
			((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
			this.SuspendLayout();
			// 
			// btnCancel
			// 
			this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
			this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
			this.btnCancel.Location = new System.Drawing.Point(135, 55);
			this.btnCancel.Margin = new System.Windows.Forms.Padding(4);
			this.btnCancel.Name = "btnCancel";
			this.btnCancel.Size = new System.Drawing.Size(100, 28);
			this.btnCancel.TabIndex = 3;
			this.btnCancel.Text = "Cancel";
			this.btnCancel.UseVisualStyleBackColor = true;
			// 
			// btnOk
			// 
			this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
			this.btnOk.DialogResult = System.Windows.Forms.DialogResult.OK;
			this.btnOk.Location = new System.Drawing.Point(27, 55);
			this.btnOk.Margin = new System.Windows.Forms.Padding(4);
			this.btnOk.Name = "btnOk";
			this.btnOk.Size = new System.Drawing.Size(100, 28);
			this.btnOk.TabIndex = 2;
			this.btnOk.Text = "OK";
			this.btnOk.UseVisualStyleBackColor = true;
			this.btnOk.Click += new System.EventHandler(this.OnClick);
			// 
			// tableLayoutPanel1
			// 
			this.tableLayoutPanel1.AutoSize = true;
			this.tableLayoutPanel1.ColumnCount = 2;
			this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
			this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
			this.tableLayoutPanel1.Location = new System.Drawing.Point(16, 15);
			this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4);
			this.tableLayoutPanel1.Name = "tableLayoutPanel1";
			this.tableLayoutPanel1.RowCount = 1;
			this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
			this.tableLayoutPanel1.Size = new System.Drawing.Size(219, 25);
			this.tableLayoutPanel1.TabIndex = 4;
			// 
			// errorProvider
			// 
			this.errorProvider.ContainerControl = this;
			// 
			// DynamicForm
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(251, 98);
			this.Controls.Add(this.tableLayoutPanel1);
			this.Controls.Add(this.btnCancel);
			this.Controls.Add(this.btnOk);
			this.Margin = new System.Windows.Forms.Padding(4);
			this.Name = "DynamicForm";
			this.Text = "DialogBuilder";
			this.TopMost = true;
			((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
			this.ResumeLayout(false);
			this.PerformLayout();

		}

		#endregion

		private System.Windows.Forms.Button btnCancel;
		private System.Windows.Forms.Button btnOk;
		private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
		private System.Windows.Forms.ErrorProvider errorProvider;
		private System.Windows.Forms.ToolTip toolTip;
	}
}

Open in new window

SupportingObjects.cs -
using System;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace EE_Q29157886
{
	class Container
	{
		[DisplaySettings(ReadOnly = true, Width = 200)]
		public int ContainerID { get; set; }
		[DisplaySettings(Width = 200)]
		public string Description { get; set; }
		[DisplaySettings(Width = 200)]
		public double CapacityWeight { get; set; }
		[DisplaySettings(Width = 200)]
		public double CapacityCube { get; set; }
	}

	internal class ControlFactory<T>
	{
		internal static Control CreateControl(T item, PropertyInfo property)
		{
			Control ctrl = null;
			Type type = property.PropertyType;

			// The control depends on the property type
			if (type == typeof(string))
			{
				ctrl = new TextBox();
				TextBox textbox = ctrl as TextBox;
				textbox.Name = $"tbx{property.Name}";
				textbox.Text = (string)property.GetValue(item, null);
				textbox.Margin = new Padding(3, 3, 16, 0);
			}
			else if (type == typeof(char))
			{
				ctrl = new TextBox();
				TextBox textbox = ctrl as TextBox;
				textbox.MaxLength = 1;
				textbox.Name = $"tbx{property.Name}";
				textbox.Width = 20;
				textbox.Text = Convert.ToString(property.GetValue(item, null));
				textbox.Margin = new Padding(3, 3, 16, 0);
			}
			else if (type == typeof(int))
			{
				ctrl = new NumericUpDown();
				NumericUpDown numeric = ctrl as NumericUpDown;
				numeric.Name = $"nud{property.Name}";
				numeric.Value = Convert.ToDecimal(property.GetValue(item, null));
			}
			else if (type == typeof(double))
			{
				ctrl = new NumericUpDown();
				NumericUpDown numeric = ctrl as NumericUpDown;
				numeric.DecimalPlaces = 2;
				numeric.Name = $"nud{property.Name}";
				numeric.Value = (decimal)Convert.ToDouble(property.GetValue(item, null));
			}
			else if (type == typeof(decimal))
			{
				ctrl = new NumericUpDown();
				NumericUpDown numeric = ctrl as NumericUpDown;
				numeric.DecimalPlaces = 2;
				numeric.Name = $"nud{property.Name}";
				numeric.Value = Convert.ToDecimal(property.GetValue(item, null));
			}
			else if (type == typeof(bool))
			{
				ctrl = new CheckBox();
				CheckBox checkbox = ctrl as CheckBox;
				checkbox.Name = $"cbx{property.Name}";
				checkbox.Checked = Convert.ToBoolean(property.GetValue(item, null));
			}
			else if (type.BaseType == typeof(Enum))
			{
				ctrl = new ComboBox();
				ComboBox dropdown = ctrl as ComboBox;
				dropdown.DropDownStyle = ComboBoxStyle.DropDownList;
				dropdown.Name = "ddl{property.Name}";
				string[] names = Enum.GetNames(type);
				string value = Convert.ToString(property.GetValue(item, null));
				foreach (var name in names)
				{
					dropdown.Items.Add(name);
					if (name == value)
					{
						dropdown.SelectedIndex = dropdown.Items.Count - 1;
					}
				}
			}
			else if (type == typeof(DateTime))
			{
				ctrl = new DateTimePicker();
				DateTimePicker date = ctrl as DateTimePicker;
				DateTime dateValue = Convert.ToDateTime(property.GetValue(item, null));
				date.Name = $"dtp{property.Name}";
				if (dateValue < date.MinDate)
				{
					dateValue = date.MinDate;
				}

				if (dateValue > date.MaxDate)
				{
					dateValue = date.MaxDate;
				}

				date.Value = dateValue;
			}
			if (ctrl != null)
			{
				ControlTag tag = new ControlTag();
				tag.PropertyName = property.Name;
				tag.PropertyType = property.PropertyType;
				ctrl.Tag = tag;
			}
			return ctrl;
		}

		/// <summary>
		/// Creates a new instance of the Label control using the specified text value.
		/// </summary>
		/// <param name="text"></param>
		/// <returns></returns>
		internal static Label CreateLabel(string text)
		{
			Label label = new Label();
			label.Name = $"lbl{text}";
			label.Text = $"{GetLabel(text)}:";
			label.AutoSize = true;
			label.Margin = new Padding(3, 6, 6, 0);
			return label;
		}

		/// <summary>
		/// Returns a friendly label from the supplied name. For example, the
		/// string "firstName" would be returned as "First Name".
		/// </summary>
		/// <param name="text"></param>
		/// <returns></returns>
		private static string GetLabel(string text)
		{
			bool isFirst = true;
			StringBuilder sb = new StringBuilder();
			foreach (char c in text.ToCharArray())
			{
				if (isFirst)
				{
					sb.Append(char.ToUpper(c));
					isFirst = false;
				}
				else
				{
					if (char.IsUpper(c))
						sb.Append(' ');
					sb.Append(c);
				}
			}
			return sb.ToString();
		}
	}

	internal class ControlTag
	{
		public string CustomLabel { get; set; }
		public string ErrorMessage { get; set; }
		public string PropertyName { get; set; }
		public Type PropertyType { get; set; }

		public bool IsRequired
		{
			get { return !string.IsNullOrEmpty(ErrorMessage); }
		}
	}

	[AttributeUsage(AttributeTargets.Property)]
	public class DisplaySettingsAttribute : Attribute
	{
		public string Label { get; set; }
		public string Description { get; set; }
		public bool ReadOnly { get; set; }
		public bool Visible { get; set; }
		public int Width { get; set; }

		public DisplaySettingsAttribute()
		{
			Visible = true;
		}
	}

	[AttributeUsage(AttributeTargets.Property)]
	public class NumericSettingsAttribute : Attribute
	{
		public float MinValue { get; set; }
		public float MaxValue { get; set; }
		public int DecimalPlaces { get; set; }
	}

	[AttributeUsage(AttributeTargets.Property)]
	public class RequiredFieldAttribute : Attribute
	{
		public string Message { get; set; }
	}
}

Open in new window

Produces the following output -Capture.PNGCapture.PNGCapture.PNGCapture.PNGCapture.PNGCapture.PNGCapture.PNGCapture.PNG-saige-
Sn0wb0yLearner

Author

Commented:
Wow! That's completely awesome but way over the top of my head it_saige! I am just starting out with learning C# winforms here, sorry I would have to study it for days to work out what you did! Lolz

Commented:
I understand that it can be a little overwhelming, at first, but you will find that this is really simple at it's core.  You are more than welcome to take what I implemented and create a new solution so that you can step through what it is doing.

-saige-
Introduction to R

R is considered the predominant language for data scientist and statisticians. Learn how to use R for your own data science projects.

Sn0wb0yLearner

Author

Commented:
Hey thanks for the encouragement it_saige. I can see the logic in what you have done and really do appreciate the effort you put into it. It makes sense in that my UI will become much cleaner, (I know it looks horrible as it is with all those button columns!) and windows user friendly.

However, as I am self learning, I was really looking for an easy way to update the property values on my existing binding list objects as I am wanting to learn these fundamental components first before diving into more complex things.

I will certainly try and use what you have done. Thanks again
Commented:
Well, what you could do is save the Container you are modifying as a variable and then when someone clicks the Save Changes button save the values from the text boxes back to the related properties on the variable.  This will automatically update the Container instance that is in the BindingList as they are (by reference) the same Container.

Proof of concept:

Form2.cs -
using System;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Windows.Forms;

namespace EE_Q29157886
{
	public partial class Form2 : Form
	{
		BindingList<Container> containers = new BindingList<Container>();
		Container current = default(Container);

		public Form2()
		{
			InitializeComponent();
			SetupCRUD(false);
		}

		private void SetupCRUD(bool updating)
		{
			tbCube.ReadOnly = tbDescription.ReadOnly = tbWeight.ReadOnly = !updating;
			btnAction.Visible = updating;
		}

		private void ClearCRUD()
		{
			tbCube.ResetText();
			tbDescription.ResetText();
			tbWeight.ResetText();
		}

		private void OnLoad(object sender, EventArgs e)
		{
			containers.Add(new Container() { ContainerID = 1, Description = "20FT GENERAL PURPOSE", CapacityWeight = 23.4, CapacityCube = 30 });
			containers.Add(new Container() { ContainerID = 2, Description = "40FT GENERAL PURPOSE", CapacityWeight = 24.5, CapacityCube = 60 });
			containers.Add(new Container() { ContainerID = 3, Description = "40FT GENERAL PURPOSE - HIGH CUBE", CapacityWeight = 25.0, CapacityCube = 70 });
			containers.Add(new Container() { ContainerID = 4, Description = "US CHEP TWO-WAY PALLET", CapacityWeight = 1.524, CapacityCube = 1.8 });

			bindingSource1.DataSource = containers;
			dgvContainers.DataSource = bindingSource1;
		}

		private void OnClick(object sender, EventArgs e)
		{
			if (sender is ToolStripMenuItem)
			{
				var mnu = sender as ToolStripMenuItem;
				if (mnu.Equals(modifyToolStripMenuItem))
				{
					current = dgvContainers?.SelectedRows?.Cast<DataGridViewRow>()?.First()?.DataBoundItem as Container;
					if (current != default(Container))
					{
						tbDescription.Text = current.Description;
						tbWeight.Text = current.CapacityWeight.ToString();
						tbCube.Text = current.CapacityCube.ToString();
						btnAction.Text = "Save Changes";
						btnAction.Tag = "Modify";
						SetupCRUD(true);
					}
					else
					{
						MessageBox.Show("No container was selected for modification.  Please select a container from the data grid and select modify again.");
					}
				}
				else if (mnu.Equals(addToolStripMenuItem))
				{
					current = new Container() { ContainerID = containers.Max(c => c.ContainerID) + 1 };
					tbDescription.Text = current.Description;
					tbWeight.Text = current.CapacityWeight.ToString();
					tbCube.Text = current.CapacityCube.ToString();
					btnAction.Text = "Add New Container";
					btnAction.Tag = "Add";
					SetupCRUD(true);
				}
				else if (mnu.Equals(removeToolStripMenuItem))
				{
					var container = dgvContainers?.SelectedRows?.Cast<DataGridViewRow>()?.First()?.DataBoundItem as Container;
					if (container != default(Container))
					{
						containers.Remove(container);
					}
					dgvContainers.Refresh();
				}
			}
			else if (sender is Button)
			{
				var btn = sender as Button;
				if (btn.Equals(btnAction))
				{
					current.Description = tbDescription.Text;
					current.CapacityWeight = Convert.ToDouble(tbWeight.Text);
					current.CapacityCube = Convert.ToDouble(tbCube.Text);
					switch (btn.Tag.ToString())
					{
						case "Add":
							containers.Add(current);
							break;
						default:
							break;
					}
					ClearCRUD();
					SetupCRUD(false);
					current = default(Container);
					dgvContainers.Refresh();
				}
			}
		}

		private void OnRowContextMenuStripNeeded(object sender, DataGridViewRowContextMenuStripNeededEventArgs e)
		{
			if (sender is DataGridView)
			{
				var grid = sender as DataGridView;
				if (!grid.SelectedRows.Contains(grid.Rows[e.RowIndex]))
					grid.Rows[e.RowIndex].Selected = true;
				e.ContextMenuStrip = contextMenuStrip1;
			}
		}
	}
}

Open in new window

Form2.Designer.cs -
namespace EE_Q29157886
{
	partial class Form2
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.splitContainer1 = new System.Windows.Forms.SplitContainer();
			this.dgvContainers = new System.Windows.Forms.DataGridView();
			this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
			this.modifyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
			this.addToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
			this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
			this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
			this.lblDescription = new System.Windows.Forms.Label();
			this.tbDescription = new System.Windows.Forms.TextBox();
			this.lblWeight = new System.Windows.Forms.Label();
			this.lblCube = new System.Windows.Forms.Label();
			this.tbWeight = new System.Windows.Forms.TextBox();
			this.tbCube = new System.Windows.Forms.TextBox();
			this.btnAction = new System.Windows.Forms.Button();
			((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
			this.splitContainer1.Panel1.SuspendLayout();
			this.splitContainer1.Panel2.SuspendLayout();
			this.splitContainer1.SuspendLayout();
			((System.ComponentModel.ISupportInitialize)(this.dgvContainers)).BeginInit();
			this.contextMenuStrip1.SuspendLayout();
			((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).BeginInit();
			this.SuspendLayout();
			// 
			// splitContainer1
			// 
			this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
			this.splitContainer1.Location = new System.Drawing.Point(0, 0);
			this.splitContainer1.Name = "splitContainer1";
			// 
			// splitContainer1.Panel1
			// 
			this.splitContainer1.Panel1.Controls.Add(this.dgvContainers);
			// 
			// splitContainer1.Panel2
			// 
			this.splitContainer1.Panel2.Controls.Add(this.btnAction);
			this.splitContainer1.Panel2.Controls.Add(this.tbCube);
			this.splitContainer1.Panel2.Controls.Add(this.tbWeight);
			this.splitContainer1.Panel2.Controls.Add(this.lblCube);
			this.splitContainer1.Panel2.Controls.Add(this.lblWeight);
			this.splitContainer1.Panel2.Controls.Add(this.tbDescription);
			this.splitContainer1.Panel2.Controls.Add(this.lblDescription);
			this.splitContainer1.Size = new System.Drawing.Size(800, 171);
			this.splitContainer1.SplitterDistance = 576;
			this.splitContainer1.TabIndex = 0;
			// 
			// dgvContainers
			// 
			this.dgvContainers.AllowUserToAddRows = false;
			this.dgvContainers.AllowUserToDeleteRows = false;
			this.dgvContainers.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
			this.dgvContainers.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells;
			this.dgvContainers.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
			this.dgvContainers.ContextMenuStrip = this.contextMenuStrip1;
			this.dgvContainers.Dock = System.Windows.Forms.DockStyle.Fill;
			this.dgvContainers.Location = new System.Drawing.Point(0, 0);
			this.dgvContainers.MultiSelect = false;
			this.dgvContainers.Name = "dgvContainers";
			this.dgvContainers.ReadOnly = true;
			this.dgvContainers.RowHeadersVisible = false;
			this.dgvContainers.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
			this.dgvContainers.Size = new System.Drawing.Size(576, 171);
			this.dgvContainers.TabIndex = 0;
			this.dgvContainers.RowContextMenuStripNeeded += new System.Windows.Forms.DataGridViewRowContextMenuStripNeededEventHandler(this.OnRowContextMenuStripNeeded);
			// 
			// contextMenuStrip1
			// 
			this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.modifyToolStripMenuItem,
            this.addToolStripMenuItem,
            this.removeToolStripMenuItem});
			this.contextMenuStrip1.Name = "contextMenuStrip1";
			this.contextMenuStrip1.Size = new System.Drawing.Size(118, 70);
			// 
			// modifyToolStripMenuItem
			// 
			this.modifyToolStripMenuItem.Name = "modifyToolStripMenuItem";
			this.modifyToolStripMenuItem.Size = new System.Drawing.Size(117, 22);
			this.modifyToolStripMenuItem.Text = "Modify";
			this.modifyToolStripMenuItem.Click += new System.EventHandler(this.OnClick);
			// 
			// addToolStripMenuItem
			// 
			this.addToolStripMenuItem.Name = "addToolStripMenuItem";
			this.addToolStripMenuItem.Size = new System.Drawing.Size(117, 22);
			this.addToolStripMenuItem.Text = "Add";
			this.addToolStripMenuItem.Click += new System.EventHandler(this.OnClick);
			// 
			// removeToolStripMenuItem
			// 
			this.removeToolStripMenuItem.Name = "removeToolStripMenuItem";
			this.removeToolStripMenuItem.Size = new System.Drawing.Size(117, 22);
			this.removeToolStripMenuItem.Text = "Remove";
			this.removeToolStripMenuItem.Click += new System.EventHandler(this.OnClick);
			// 
			// lblDescription
			// 
			this.lblDescription.AutoSize = true;
			this.lblDescription.Location = new System.Drawing.Point(3, 9);
			this.lblDescription.Name = "lblDescription";
			this.lblDescription.Size = new System.Drawing.Size(109, 13);
			this.lblDescription.TabIndex = 0;
			this.lblDescription.Text = "Container description:";
			// 
			// tbDescription
			// 
			this.tbDescription.Location = new System.Drawing.Point(6, 26);
			this.tbDescription.Name = "tbDescription";
			this.tbDescription.Size = new System.Drawing.Size(211, 20);
			this.tbDescription.TabIndex = 1;
			// 
			// lblWeight
			// 
			this.lblWeight.AutoSize = true;
			this.lblWeight.Location = new System.Drawing.Point(3, 53);
			this.lblWeight.Name = "lblWeight";
			this.lblWeight.Size = new System.Drawing.Size(44, 13);
			this.lblWeight.TabIndex = 2;
			this.lblWeight.Text = "Weight:";
			// 
			// lblCube
			// 
			this.lblCube.AutoSize = true;
			this.lblCube.Location = new System.Drawing.Point(114, 53);
			this.lblCube.Name = "lblCube";
			this.lblCube.Size = new System.Drawing.Size(35, 13);
			this.lblCube.TabIndex = 3;
			this.lblCube.Text = "Cube:";
			// 
			// tbWeight
			// 
			this.tbWeight.Location = new System.Drawing.Point(6, 69);
			this.tbWeight.Name = "tbWeight";
			this.tbWeight.Size = new System.Drawing.Size(100, 20);
			this.tbWeight.TabIndex = 4;
			// 
			// tbCube
			// 
			this.tbCube.Location = new System.Drawing.Point(117, 69);
			this.tbCube.Name = "tbCube";
			this.tbCube.Size = new System.Drawing.Size(100, 20);
			this.tbCube.TabIndex = 5;
			// 
			// btnAction
			// 
			this.btnAction.Location = new System.Drawing.Point(6, 136);
			this.btnAction.Name = "btnAction";
			this.btnAction.Size = new System.Drawing.Size(211, 23);
			this.btnAction.TabIndex = 6;
			this.btnAction.Text = "Add New Container";
			this.btnAction.UseVisualStyleBackColor = true;
			this.btnAction.Click += new System.EventHandler(this.OnClick);
			// 
			// Form2
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(800, 171);
			this.Controls.Add(this.splitContainer1);
			this.Name = "Form2";
			this.Text = "Form2";
			this.Load += new System.EventHandler(this.OnLoad);
			this.splitContainer1.Panel1.ResumeLayout(false);
			this.splitContainer1.Panel2.ResumeLayout(false);
			this.splitContainer1.Panel2.PerformLayout();
			((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
			this.splitContainer1.ResumeLayout(false);
			((System.ComponentModel.ISupportInitialize)(this.dgvContainers)).EndInit();
			this.contextMenuStrip1.ResumeLayout(false);
			((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).EndInit();
			this.ResumeLayout(false);

		}

		#endregion

		private System.Windows.Forms.SplitContainer splitContainer1;
		private System.Windows.Forms.DataGridView dgvContainers;
		private System.Windows.Forms.BindingSource bindingSource1;
		private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
		private System.Windows.Forms.ToolStripMenuItem addToolStripMenuItem;
		private System.Windows.Forms.ToolStripMenuItem modifyToolStripMenuItem;
		private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem;
		private System.Windows.Forms.TextBox tbDescription;
		private System.Windows.Forms.Label lblDescription;
		private System.Windows.Forms.Button btnAction;
		private System.Windows.Forms.TextBox tbCube;
		private System.Windows.Forms.TextBox tbWeight;
		private System.Windows.Forms.Label lblCube;
		private System.Windows.Forms.Label lblWeight;
	}
}

Open in new window

Produces the following output -Capture.PNGCapture.PNGCapture.PNGCapture.PNGCapture.PNGCapture.PNGCapture.PNGCapture.PNG-saige-
Sn0wb0yLearner

Author

Commented:
Hi it_saige,

First off, I want to thank you again for taking the time to respond to my question. As I mentioned earlier, I am just starting out and really got myself in a tangle with your solution. In hindsight, I should of provided my existing form code, as clunky as it is, to help you further understand what I was trying to do.

From reviewing that code you provided, I managed to identify and implement the updating of my bound list as intended from my original question. I am absolutely sure it is far from perfect and would appreciate any feedback you might have. As follows:

Main.cs

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.ComponentModel;
using System.Linq;
using System.Drawing;

namespace ContainerPackerWinForms
{
    public partial class Main : Form
    {
        // Create an initial arbitrary list of containers to choose from
        BindingList<Container> Containers = new BindingList<Container>();
		Container current = default(Container);

        public Main()
        {
            InitializeComponent(); 
        }
        
        private void Main_Load(object sender, EventArgs e)
        {			 
			initContainers();
			dgvContainer.DataSource = Containers;
			initContainerDGV();            
            initContainerSection();
        }
		
        #region Container
		
		// Add / edit / remove container
        private void DgvContainer_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            // Validate row selection
            if (this.dgvContainer.CurrentRow != null)
            {
                // Validate modify container button click
                if (e.ColumnIndex == this.dgvContainer.Columns["modify_container_button_column"].Index)
                {
                    // Perform a second validation of container selection            
                    if (this.dgvContainer.CurrentRow != null && this.dgvContainer.SelectedRows.Count > 0)
                    {
                        // Transfer selected cell bindings to UI controls
                        this.txtContainerDescription.Text = this.dgvContainer.SelectedCells[1].Value.ToString();
                        this.txtContainerCapacityWeight.Text = this.dgvContainer.SelectedCells[2].Value.ToString();
                        this.txtContainerCapacityCube.Text = this.dgvContainer.SelectedCells[3].Value.ToString();

                        // Change button caption and set focus to description field
                        this.btnAddUpdateContainer.Text = "Save Changes";                        
                        this.txtContainerDescription.Focus();
                    }                    
                }                
                // Validate remove container button click
                else if (e.ColumnIndex == this.dgvContainer.Columns["remove_container_button_column"].Index)
                {
                    // Perform a second validation of container selection            
                    if (this.dgvContainer.CurrentRow != null && this.dgvContainer.SelectedRows.Count > 0)
                    {
                        // TO DO: 
                        // ADD FUNCTIONALITY TO REMOVE ALL EXISTING SHIPMENT CONTAINERS AND PACKING DETAILS
                        
                        // Remove the selected container from the container list
                        Containers.RemoveAt(this.dgvContainer.CurrentRow.Index);

                        // Initialize the container section                        
                        initContainerSection();
                        this.txtShipmentName.Focus();
                    }
                }
            }
            else
            {
                // Prompt user to select a container
                MessageBox.Show("Error! Please select a container from the list.");                
            }
        }

        // Add / update container
        private void BtnAddUpdateContainer_Click(object sender, EventArgs e)
        {
            current = dgvContainer?.SelectedRows?.Cast<DataGridViewRow>()?.First()?.DataBoundItem as Container;

            // Validate add container mode
            if (this.btnAddUpdateContainer.Text == "Add New Container")
            {
                // Validate form fields
                if (!IsEmpty(this.txtContainerDescription.Text, this.txtContainerCapacityWeight.Text, this.txtContainerCapacityCube.Text))
                {
                    // Add container to list
                    Containers.Add(new Container()
                    {
                        Description = this.txtContainerDescription.Text,
                        CapacityWeight = Convert.ToDouble(this.txtContainerCapacityWeight.Text),
                        CapacityCube = Convert.ToDouble(this.txtContainerCapacityCube.Text)
                    });

                    // Clear and initialize the container section                
                    this.dgvContainer.ClearSelection();
                    initContainerSection();
                    this.txtShipmentName.Focus();
                }
                else
                {
                    // Prompt user to provide required values
                    MessageBox.Show("Error! Please provide values for all data entry fields.");
                    initContainerSection();
                    this.txtContainerDescription.Focus();
                }
            }
            // Validate update container mode
            else if (this.btnAddUpdateContainer.Text == "Save Changes")
            {
                if (this.dgvContainer.CurrentRow != null && this.dgvContainer.SelectedRows.Count > 0)
                {
                    if (current != default(Container))
                    {
                        current.Description = txtContainerDescription.Text;
                        current.CapacityWeight = Convert.ToDouble(txtContainerCapacityWeight.Text);
                        current.CapacityCube = Convert.ToDouble(txtContainerCapacityCube.Text);
                    }                    

                    // Clear and initialize the container section                
                    this.dgvContainer.ClearSelection();
                    initContainerSection();                    
                }
            }
        }
		
        // Initializes a list of containers
        private void initContainers()
        {
            // Add some containers to the container list
            Containers.Add(new Container() { Description = "20FT GENERAL PURPOSE", CapacityWeight = 23.4, CapacityCube = 30 });
            Containers.Add(new Container() { Description = "40FT GENERAL PURPOSE", CapacityWeight = 24.5, CapacityCube = 60 });
            Containers.Add(new Container() { Description = "40FT GENERAL PURPOSE - HIGH CUBE", CapacityWeight = 25.0, CapacityCube = 70 });
            Containers.Add(new Container() { Description = "US CHEP TWO-WAY PALLET", CapacityWeight = 1.524, CapacityCube = 1.8 });
        }
        
        // Initializes container section
        private void initContainerSection()
        {
            if (this.dgvContainer.Rows.Count > 0)
            {
                clearContainerFields();
                this.dgvContainer.Enabled = true;
                this.txtContainerDescription.Enabled = true;
                this.txtContainerCapacityWeight.Enabled = true;
                this.txtContainerCapacityCube.Enabled = true;
                this.btnAddUpdateContainer.Text = "Add New Container";
                this.btnAddUpdateContainer.Enabled = true;                
            }
            else
            {
                clearContainerFields();
                this.dgvContainer.Enabled = false;
                this.txtContainerDescription.Enabled = false;
                this.txtContainerCapacityWeight.Enabled = false;
                this.txtContainerCapacityCube.Enabled = false;
                this.btnAddUpdateContainer.Text = "Add New Container";
                this.btnAddUpdateContainer.Enabled = true;
            }
        }

        // Clears container entry fields
        private void clearContainerFields()
        {
            this.txtContainerCapacityCube.Text = null;
            this.txtContainerCapacityWeight.Text = null;
            this.txtContainerDescription.Text = null;
        }

		// Initializes container datagrid
        private void initContainerDGV()
        {
            // Set control properties            
            this.dgvContainer.AutoGenerateColumns = false;
            this.dgvContainer.MultiSelect = false;
            this.dgvContainer.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            this.dgvContainer.RowHeadersVisible = false;
            this.dgvContainer.RowsDefaultCellStyle.BackColor = Color.White;
            this.dgvContainer.AlternatingRowsDefaultCellStyle.BackColor = Color.FromArgb(240, 244, 244);
            this.dgvContainer.ScrollBars = ScrollBars.Vertical;

            // Set column definitions
            this.dgvContainer.Columns[0].HeaderText = "Container ID";
            this.dgvContainer.Columns[0].DataPropertyName = "ContainerID";
            this.dgvContainer.Columns[0].MinimumWidth = 85;
            this.dgvContainer.Columns[0].Width = 90;
            this.dgvContainer.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;

            this.dgvContainer.Columns[1].HeaderText = "Container Description";
            this.dgvContainer.Columns[1].DataPropertyName = "Description";
            this.dgvContainer.Columns[1].MinimumWidth = 220;
            this.dgvContainer.Columns[1].Width = 230;
            this.dgvContainer.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;

            this.dgvContainer.Columns[2].HeaderText = "Weight Capacity (MT)";
            this.dgvContainer.Columns[2].DataPropertyName = "CapacityWeight";
            this.dgvContainer.Columns[2].MinimumWidth = 130;
            this.dgvContainer.Columns[2].Width = 135;
            this.dgvContainer.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.dgvContainer.Columns[2].DefaultCellStyle.Format = "0.00";

            this.dgvContainer.Columns[3].HeaderText = "Cube Capacity (CBM)";
            this.dgvContainer.Columns[3].DataPropertyName = "CapacityCube";
            this.dgvContainer.Columns[3].MinimumWidth = 130;
            this.dgvContainer.Columns[3].Width = 135;
            this.dgvContainer.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.dgvContainer.Columns[3].DefaultCellStyle.Format = "0.00";

            // Edit container button column
            DataGridViewButtonColumn modifyContainerButtonColumn = new DataGridViewButtonColumn();
            modifyContainerButtonColumn.Name = "modify_container_button_column";
            modifyContainerButtonColumn.HeaderText = "Modify";
            modifyContainerButtonColumn.Text = "Modify";
            modifyContainerButtonColumn.UseColumnTextForButtonValue = true;
            int columnIndex1 = 4;
            if (this.dgvContainer.Columns["modify_container_button_column"] == null)
            {
                this.dgvContainer.Columns.Insert(columnIndex1, modifyContainerButtonColumn);
            }
            
            // Add container to shipment button column
            DataGridViewButtonColumn addContainerToShipmentButtonColumn = new DataGridViewButtonColumn();
            addContainerToShipmentButtonColumn.Name = "add_container_to_shipment_button_column";
            addContainerToShipmentButtonColumn.HeaderText = "Add";
            addContainerToShipmentButtonColumn.Text = "Add";
            addContainerToShipmentButtonColumn.UseColumnTextForButtonValue = true;
            int columnIndex2 = 5;
            if (this.dgvContainer.Columns["add_container_to_shipment_button_column"] == null)
            {
                this.dgvContainer.Columns.Insert(columnIndex2, addContainerToShipmentButtonColumn);
            }

            // Remove container button column
            DataGridViewButtonColumn removeContainerButtonColumn = new DataGridViewButtonColumn();
            removeContainerButtonColumn.Name = "remove_container_button_column";
            removeContainerButtonColumn.HeaderText = "Remove";
            removeContainerButtonColumn.Text = "Remove";
            removeContainerButtonColumn.UseColumnTextForButtonValue = true;
            int columnIndex3 = 6;
            if (this.dgvContainer.Columns["remove_container_button_column"] == null)
            {
                this.dgvContainer.Columns.Insert(columnIndex3, removeContainerButtonColumn);
            }
        }
        
        #endregion
		
        #region Form Helper Methods

        // Function to validate textbox entries
        private static bool IsEmpty(params string[] args)
        {
            if (args.Length == 0) return true;
            return args.Any(p => string.IsNullOrEmpty(p));
        }

        #endregion
    }
}

Open in new window


ExtensionMethods.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExtensionMethods
{
    public static class Extension
    {
        public static string NewID()
        {
            return Guid.NewGuid().ToString().Replace("-", string.Empty).Replace("=", string.Empty).Replace("+", string.Empty).Substring(0, 6);
        }
    }
}

Open in new window


Container.cs

using System;
using ExtensionMethods;

namespace ContainerPackerWinForms
{
    public class Container
    {
        #region Properties
        
        public string ContainerID { get; private set; }        
        public string Description { get; set; }        
        public double CapacityWeight { get; set; }        
        public double CapacityCube { get; set; }
        
        #endregion  

        #region Constructor

        // Default constructor
        public Container()
        {
            ContainerID = Extension.NewID();
        }

        #endregion
    }
}

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial