129 lines
5.7 KiB
C#
129 lines
5.7 KiB
C#
using System.ComponentModel;
|
|
using trakker.Models;
|
|
|
|
namespace trakker.Forms
|
|
{
|
|
/// <summary>
|
|
/// Form used to view and edit a <see cref="Project"/> model. Fields on the form
|
|
/// are data-bound to the provided project instance and basic validation is
|
|
/// performed on required fields.
|
|
/// </summary>
|
|
public partial class ProjectForm : Form
|
|
{
|
|
/// <summary>
|
|
/// The project instance being edited by this form.
|
|
/// </summary>
|
|
private readonly Project _project;
|
|
|
|
private BindingList<Client>? _clients;
|
|
|
|
/// <summary>
|
|
/// Binding source that connects the project 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="ProjectForm"/> class bound to
|
|
/// the provided <paramref name="project"/>. Sets up data bindings for all
|
|
/// visible input controls and configures dialog button behavior.
|
|
/// </summary>
|
|
/// <param name="project">The <see cref="Project"/> instance to edit. Must not be null.</param>
|
|
/// <param name="clients">The list of <see cref="Client"/> instances to select from. Must not be null.</param>
|
|
/// <param name="status">The binding source for status values. Must not be null.</param>
|
|
public ProjectForm(Project project, BindingList<Client> clients, BindingSource status)
|
|
{
|
|
_project = project;
|
|
_clients = clients;
|
|
InitializeComponent();
|
|
|
|
Text = "Project Details";
|
|
|
|
comboBoxClient.DataSource = _clients;
|
|
comboBoxClient.DisplayMember = "DisplayMember";
|
|
comboBoxClient.ValueMember = "ClientId";
|
|
|
|
dateTimePickerStartDate.Format = DateTimePickerFormat.Custom;
|
|
dateTimePickerStartDate.CustomFormat = "yyyy-MM-dd";
|
|
dateTimePickerEndDate.Format = DateTimePickerFormat.Custom;
|
|
dateTimePickerEndDate.CustomFormat = "yyyy-MM-dd";
|
|
|
|
// Bind model properties to controls so the UI reflects and updates the model.
|
|
bindingSource.DataSource = _project;
|
|
comboBoxClient.DataBindings.Add("SelectedValue", bindingSource, "ClientId", true);
|
|
textBoxName.DataBindings.Add("Text", bindingSource, "ProjectName", true);
|
|
richTextBoxDescription.DataBindings.Add("Text", bindingSource, "Description", true);
|
|
dateTimePickerStartDate.DataBindings.Add("Value", bindingSource, "StartDate", true);
|
|
dateTimePickerEndDate.DataBindings.Add("Value", bindingSource, "EndDate", true);
|
|
textBoxHourlyRate.DataBindings.Add("Text", bindingSource, "HourlyRate", true);
|
|
textBoxBudget.DataBindings.Add("Text", bindingSource, "Budget", true);
|
|
comboBoxStatus.DataSource = status;
|
|
comboBoxStatus.DisplayMember = "Display";
|
|
comboBoxStatus.ValueMember = "Value";
|
|
comboBoxStatus.DataBindings.Add("SelectedValue", bindingSource, "Status", true);
|
|
richTextBoxNotes.DataBindings.Add("Text", bindingSource, "Notes", true);
|
|
|
|
labelCreatedUpdatedDT.Text = $"Created: {_project.CreatedAt:G} | Updated: {_project.UpdatedAt:G}";
|
|
|
|
// Configure dialog buttons and window behavior.
|
|
buttonOkay.DialogResult = DialogResult.OK;
|
|
buttonCancel.DialogResult = DialogResult.Cancel;
|
|
this.CancelButton = buttonCancel;
|
|
this.StartPosition = FormStartPosition.CenterParent;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the <see cref="Project"/> instance edited by the form.
|
|
/// </summary>
|
|
public Project Project { get => _project; private set { } }
|
|
|
|
public BindingList<Client>? Clients { get => _clients; set { _clients = value; } }
|
|
|
|
/// <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, "");
|
|
//}
|
|
}
|
|
|
|
}
|
|
}
|
|
|