trakker/Forms/ClientForm.cs

111 lines
4.9 KiB
C#

using trakker.Models;
namespace trakker.Forms
{
/// <summary>
/// Form used to view and edit a <see cref="Client"/> model. Fields on the form
/// are data-bound to the provided client instance and basic validation is
/// performed on required fields.
/// </summary>
public partial class ClientForm : Form
{
/// <summary>
/// The client instance being edited by this form.
/// </summary>
private readonly Client _client;
/// <summary>
/// Binding source that connects the client model to the form controls.
/// </summary>
private BindingSource bindingSource = new BindingSource();
/// <summary>
/// Error provider used to display validation errors next to input controls.
/// </summary>
private ErrorProvider errorProvider = new ErrorProvider();
/// <summary>
/// Initializes a new instance of the <see cref="ClientForm"/> class bound to
/// the provided <paramref name="client"/>. Sets up data bindings for all
/// visible input controls and configures dialog button behavior.
/// </summary>
/// <param name="client">The <see cref="Client"/> instance to edit. Must not be null.</param>
/// <param name="states">The binding source for state values. Must not be null.</param>
public ClientForm(Client client, BindingSource states)
{
_client = client;
InitializeComponent();
Text = "Client Details";
// Bind model properties to controls so the UI reflects and updates the model.
bindingSource.DataSource = _client;
textBoxName.DataBindings.Add("Text", bindingSource, "Name", true);
textBoxCompany.DataBindings.Add("Text", bindingSource, "Company", true);
textBoxEmail.DataBindings.Add("Text", bindingSource, "Email", true);
maskedTextBox_Phone.DataBindings.Add("Text", bindingSource, "Phone", true);
textBoxAddressStreet.DataBindings.Add("Text", bindingSource, "AddressStreet", true);
textBoxAddressCity.DataBindings.Add("Text", bindingSource, "AddressCity", true);
comboBoxAddressState.DataSource = states;
comboBoxAddressState.DisplayMember = "Display";
comboBoxAddressState.ValueMember = "Value";
comboBoxAddressState.DataBindings.Add("SelectedValue", bindingSource, "AddressState", true);
maskedTextBoxAddressPostal.DataBindings.Add("Text", bindingSource, "AddressPostal", true);
richTextBoxNotes.DataBindings.Add("Text", bindingSource, "Notes", true);
labelCreatedUpdatedDT.Text = $"Created: {_client.CreatedAt:G} | Updated: {_client.UpdatedAt:G}";
// Configure dialog buttons and window behavior.
buttonOkay.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
this.CancelButton = CancelButton;
this.StartPosition = FormStartPosition.CenterParent;
}
/// <summary>
/// Gets the <see cref="Client"/> instance edited by the form.
/// </summary>
public Client Client { get => _client; private set { } }
/// <summary>
/// Validates the Name field. If the name is empty or whitespace, an error is set
/// on the <see cref="errorProvider"/> and the event is canceled to prevent the
/// form from closing.
/// </summary>
private void textBoxName_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
if (string.IsNullOrWhiteSpace(textBoxName.Text))
{
errorProvider.SetError(textBoxName, "Name is required.");
errorProvider.SetIconAlignment(textBoxName, ErrorIconAlignment.MiddleRight);
errorProvider.SetIconPadding(textBoxName, 2);
e.Cancel = true;
}
else
{
errorProvider.SetError(textBoxName, "");
}
}
/// <summary>
/// Validates the Email field. If the email is empty or whitespace, an error is set
/// on the <see cref="errorProvider"/> and the event is canceled to prevent the
/// form from closing. Note: this validation only checks presence, not format.
/// </summary>
private void textBoxEmail_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
if (string.IsNullOrWhiteSpace(textBoxEmail.Text))
{
errorProvider.SetError(textBoxEmail, "Email is required.");
errorProvider.SetIconAlignment(textBoxEmail, ErrorIconAlignment.MiddleRight);
errorProvider.SetIconPadding(textBoxEmail, 2);
e.Cancel = true;
}
else
{
errorProvider.SetError(textBoxEmail, "");
}
}
}
}