feat: set & get validation

This commit is contained in:
2026-02-23 17:35:49 +01:00
parent 2aeee0a009
commit 160352383a
5 changed files with 165 additions and 25 deletions

View File

@@ -11,14 +11,73 @@ namespace CarManagerV3
/// </summary> /// </summary>
public class Car public class Car
{ {
public int Id; private int id;
public string Make; private string make;
public string Model; private string model;
public int Year; private int year;
public string Color; private string color;
public int Mileage; private int mileage;
public decimal Price; private decimal price;
public int Order; private int order;
public int Id { get => id;
set {
if (value < 0) throw new ArgumentException("Id cannot be negative.");
id = value;
}
}
public string Make { get => make;
set
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Make cannot be empty.");
make = value;
}
}
public string Model { get => model;
set
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Model cannot be empty.");
model = value;
}
}
public int Year { get => year;
set
{
if (value < 1886 || value > DateTime.Now.Year + 1) throw new ArgumentException("Year must be between 1886 and next year.");
Console.WriteLine($"Updating year to {year}");
year = value;
}
}
public string Color { get => color;
set
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Color cannot be empty.");
color = value;
}
}
public int Mileage { get => mileage;
set
{
if (value < 0) throw new ArgumentException("Mileage cannot be negative.");
mileage = value;
}
}
public decimal Price { get => price;
set
{
if (value < 0) throw new ArgumentException("Price cannot be negative.");
price = value;
}
}
public int Order { get => order; set => order = value; }
//TODO: Make Id read-only CUID. Allows for better integrity, especially when merging. //TODO: Make Id read-only CUID. Allows for better integrity, especially when merging.
//TODO: Add buying price and automatic calculation of profit/loss with selling price suggestion. //TODO: Add buying price and automatic calculation of profit/loss with selling price suggestion.
@@ -38,6 +97,7 @@ namespace CarManagerV3
/// <param name="order">The order.</param> /// <param name="order">The order.</param>
public Car(int id, string make, string model, int year, string color, int mileage, decimal price, int order = 0) public Car(int id, string make, string model, int year, string color, int mileage, decimal price, int order = 0)
{ {
// Sets the properties using the setters to ensure validation is applied.
this.Id = id; this.Id = id;
this.Make = make; this.Make = make;
this.Model = model; this.Model = model;

View File

@@ -120,6 +120,7 @@
this.tbxMake.Size = new System.Drawing.Size(473, 22); this.tbxMake.Size = new System.Drawing.Size(473, 22);
this.tbxMake.TabIndex = 1; this.tbxMake.TabIndex = 1;
this.tbxMake.TextChanged += new System.EventHandler(this.tbxMake_TextChanged); this.tbxMake.TextChanged += new System.EventHandler(this.tbxMake_TextChanged);
this.tbxMake.Leave += new System.EventHandler(this.tbxMake_Leave);
// //
// label2 // label2
// //
@@ -138,6 +139,7 @@
this.tbxModel.Size = new System.Drawing.Size(473, 22); this.tbxModel.Size = new System.Drawing.Size(473, 22);
this.tbxModel.TabIndex = 2; this.tbxModel.TabIndex = 2;
this.tbxModel.TextChanged += new System.EventHandler(this.tbxModel_TextChanged); this.tbxModel.TextChanged += new System.EventHandler(this.tbxModel_TextChanged);
this.tbxModel.Leave += new System.EventHandler(this.tbxModel_Leave);
// //
// label3 // label3
// //
@@ -239,6 +241,7 @@
this.tbxColor.Size = new System.Drawing.Size(473, 22); this.tbxColor.Size = new System.Drawing.Size(473, 22);
this.tbxColor.TabIndex = 4; this.tbxColor.TabIndex = 4;
this.tbxColor.TextChanged += new System.EventHandler(this.tbxColor_TextChanged); this.tbxColor.TextChanged += new System.EventHandler(this.tbxColor_TextChanged);
this.tbxColor.Leave += new System.EventHandler(this.tbxColor_Leave);
// //
// nudMileage // nudMileage
// //

View File

@@ -29,34 +29,85 @@ namespace CarManagerV3
lblID.Text = $"ID: {car.Id}"; lblID.Text = $"ID: {car.Id}";
} }
/// <summary>
/// Updates a car property safely by executing the update action and reverting it if an exception occurs.
/// </summary>
/// <param name="updateAction">The update action.</param>
/// <param name="revertAction">The action to perform when the update fails.</param>
private void SafeUpdate(Action updateAction, Action revertAction)
{
try
{
updateAction();
}
catch (ArgumentException ex)
{
MessageBox.Show(ex.Message, "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error);
revertAction();
}
}
//private string ValueOrFormer(string newValue, string oldValue)
//{
// return string.IsNullOrWhiteSpace(newValue) ? oldValue : newValue;
//}
private T ValueOrFormer<T>(T newValue, T oldValue)
{
if (newValue is string str)
{
return string.IsNullOrWhiteSpace(str) ? oldValue : newValue;
}
return newValue;
}
private void tbxMake_TextChanged(object sender, EventArgs e) private void tbxMake_TextChanged(object sender, EventArgs e)
{ {
car.Make = tbxMake.Text; SafeUpdate(
() => car.Make = ValueOrFormer(tbxMake.Text, car.Make),
() => tbxMake.Text = car.Make
);
} }
private void tbxModel_TextChanged(object sender, EventArgs e) private void tbxModel_TextChanged(object sender, EventArgs e)
{ {
car.Model = tbxModel.Text; SafeUpdate(
() => car.Model = ValueOrFormer(tbxModel.Text, car.Model),
() => tbxModel.Text = car.Model
);
} }
private void nudYear_ValueChanged(object sender, EventArgs e) private void nudYear_ValueChanged(object sender, EventArgs e)
{ {
car.Year = (int)nudYear.Value; Console.WriteLine("Year value changed: " + nudYear.Value);
SafeUpdate(
() => car.Year = (int)ValueOrFormer(nudYear.Value, car.Year),
() => nudYear.Value = car.Year
);
} }
private void tbxColor_TextChanged(object sender, EventArgs e) private void tbxColor_TextChanged(object sender, EventArgs e)
{ {
car.Color = tbxColor.Text; SafeUpdate(
() => car.Color = ValueOrFormer(tbxColor.Text, car.Color),
() => tbxColor.Text = car.Color
);
} }
private void nudMileage_ValueChanged(object sender, EventArgs e) private void nudMileage_ValueChanged(object sender, EventArgs e)
{ {
car.Mileage = (int)nudMileage.Value; SafeUpdate(
() => car.Mileage = (int)nudMileage.Value,
() => nudMileage.Value = car.Mileage
);
} }
private void nudPrice_ValueChanged(object sender, EventArgs e) private void nudPrice_ValueChanged(object sender, EventArgs e)
{ {
car.Price = nudPrice.Value; SafeUpdate(
() => car.Price = nudPrice.Value,
() => nudPrice.Value = car.Price
);
} }
private async void btnSave_Click(object sender, EventArgs e) private async void btnSave_Click(object sender, EventArgs e)
@@ -113,5 +164,22 @@ namespace CarManagerV3
} }
return base.ProcessCmdKey(ref msg, keyData); return base.ProcessCmdKey(ref msg, keyData);
} }
private void tbxMake_Leave(object sender, EventArgs e)
{
tbxMake.Text = ValueOrFormer(tbxMake.Text, car.Make);
}
private void tbxModel_Leave(object sender, EventArgs e)
{
tbxModel.Text = ValueOrFormer(tbxModel.Text, car.Model);
}
private void tbxColor_Leave(object sender, EventArgs e)
{
tbxColor.Text = ValueOrFormer(tbxColor.Text, car.Color);
}
} }
} }

View File

@@ -63,8 +63,16 @@ namespace CarManagerV3
{ {
Console.Error.WriteLine($"Error loading image: {ex.Message}"); Console.Error.WriteLine($"Error loading image: {ex.Message}");
} }
try
{
return Image.FromFile("images/no_image_available.png"); return Image.FromFile("images/no_image_available.png");
} }
catch (Exception ex)
{
Console.Error.WriteLine($"Error loading fallback image: {ex.Message}");
return null;
}
}
/// <summary> /// <summary>
/// Fetches an image for a Car from https://cdn.imagin.studio/getimage if it does not already exist locally and saves it to images/<c>Make_Model_Year_Color.webp</>. /// Fetches an image for a Car from https://cdn.imagin.studio/getimage if it does not already exist locally and saves it to images/<c>Make_Model_Year_Color.webp</>.

View File

@@ -70,7 +70,7 @@
this.flpCars.AutoScroll = true; this.flpCars.AutoScroll = true;
this.flpCars.AutoScrollMargin = new System.Drawing.Size(0, 200); this.flpCars.AutoScrollMargin = new System.Drawing.Size(0, 200);
this.flpCars.Dock = System.Windows.Forms.DockStyle.Fill; this.flpCars.Dock = System.Windows.Forms.DockStyle.Fill;
this.flpCars.Location = new System.Drawing.Point(3, 67); this.flpCars.Location = new System.Drawing.Point(3, 71);
this.flpCars.Name = "flpCars"; this.flpCars.Name = "flpCars";
this.flpCars.Size = new System.Drawing.Size(796, 412); this.flpCars.Size = new System.Drawing.Size(796, 412);
this.flpCars.TabIndex = 1; this.flpCars.TabIndex = 1;
@@ -83,7 +83,7 @@
this.tableLayoutPanel2.Controls.Add(this.tbxSearch, 0, 0); this.tableLayoutPanel2.Controls.Add(this.tbxSearch, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.btnNewCar, 1, 0); this.tableLayoutPanel2.Controls.Add(this.btnNewCar, 1, 0);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 27); this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 31);
this.tableLayoutPanel2.Name = "tableLayoutPanel2"; this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 1; this.tableLayoutPanel2.RowCount = 1;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
@@ -112,11 +112,12 @@
// //
// menuStrip1 // menuStrip1
// //
this.menuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20);
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem}); this.fileToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(802, 24); this.menuStrip1.Size = new System.Drawing.Size(802, 28);
this.menuStrip1.TabIndex = 3; this.menuStrip1.TabIndex = 3;
this.menuStrip1.Text = "menuStrip1"; this.menuStrip1.Text = "menuStrip1";
// //
@@ -130,48 +131,48 @@
this.recentFilesToolStripMenuItem, this.recentFilesToolStripMenuItem,
this.revealInFileExplorerToolStripMenuItem}); this.revealInFileExplorerToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); this.fileToolStripMenuItem.Size = new System.Drawing.Size(46, 24);
this.fileToolStripMenuItem.Text = "File"; this.fileToolStripMenuItem.Text = "File";
// //
// openToolStripMenuItem // openToolStripMenuItem
// //
this.openToolStripMenuItem.Name = "openToolStripMenuItem"; this.openToolStripMenuItem.Name = "openToolStripMenuItem";
this.openToolStripMenuItem.Size = new System.Drawing.Size(187, 22); this.openToolStripMenuItem.Size = new System.Drawing.Size(238, 26);
this.openToolStripMenuItem.Text = "Open"; this.openToolStripMenuItem.Text = "Open";
this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
// //
// saveToolStripMenuItem // saveToolStripMenuItem
// //
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
this.saveToolStripMenuItem.Size = new System.Drawing.Size(187, 22); this.saveToolStripMenuItem.Size = new System.Drawing.Size(238, 26);
this.saveToolStripMenuItem.Text = "Save"; this.saveToolStripMenuItem.Text = "Save";
this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click); this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
// //
// saveAsToolStripMenuItem // saveAsToolStripMenuItem
// //
this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem"; this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem";
this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(187, 22); this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(238, 26);
this.saveAsToolStripMenuItem.Text = "Save as"; this.saveAsToolStripMenuItem.Text = "Save as";
this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.saveAsToolStripMenuItem_Click); this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.saveAsToolStripMenuItem_Click);
// //
// importToolStripMenuItem // importToolStripMenuItem
// //
this.importToolStripMenuItem.Name = "importToolStripMenuItem"; this.importToolStripMenuItem.Name = "importToolStripMenuItem";
this.importToolStripMenuItem.Size = new System.Drawing.Size(187, 22); this.importToolStripMenuItem.Size = new System.Drawing.Size(238, 26);
this.importToolStripMenuItem.Text = "Import"; this.importToolStripMenuItem.Text = "Import";
this.importToolStripMenuItem.Click += new System.EventHandler(this.importToolStripMenuItem_Click); this.importToolStripMenuItem.Click += new System.EventHandler(this.importToolStripMenuItem_Click);
// //
// recentFilesToolStripMenuItem // recentFilesToolStripMenuItem
// //
this.recentFilesToolStripMenuItem.Name = "recentFilesToolStripMenuItem"; this.recentFilesToolStripMenuItem.Name = "recentFilesToolStripMenuItem";
this.recentFilesToolStripMenuItem.Size = new System.Drawing.Size(187, 22); this.recentFilesToolStripMenuItem.Size = new System.Drawing.Size(238, 26);
this.recentFilesToolStripMenuItem.Text = "Recent Files"; this.recentFilesToolStripMenuItem.Text = "Recent Files";
this.recentFilesToolStripMenuItem.Click += new System.EventHandler(this.recentFilesToolStripMenuItem_Click); this.recentFilesToolStripMenuItem.Click += new System.EventHandler(this.recentFilesToolStripMenuItem_Click);
// //
// revealInFileExplorerToolStripMenuItem // revealInFileExplorerToolStripMenuItem
// //
this.revealInFileExplorerToolStripMenuItem.Name = "revealInFileExplorerToolStripMenuItem"; this.revealInFileExplorerToolStripMenuItem.Name = "revealInFileExplorerToolStripMenuItem";
this.revealInFileExplorerToolStripMenuItem.Size = new System.Drawing.Size(187, 22); this.revealInFileExplorerToolStripMenuItem.Size = new System.Drawing.Size(238, 26);
this.revealInFileExplorerToolStripMenuItem.Text = "Reveal in File Explorer"; this.revealInFileExplorerToolStripMenuItem.Text = "Reveal in File Explorer";
this.revealInFileExplorerToolStripMenuItem.Click += new System.EventHandler(this.revealInFileExplorerToolStripMenuItem_Click); this.revealInFileExplorerToolStripMenuItem.Click += new System.EventHandler(this.revealInFileExplorerToolStripMenuItem_Click);
// //