Needing help updating a TimeSpan value using form field in Visual Studio

70 Views Asked by At

I have a Visual Studio project using supportedRuntime version="v4.0" and .NETFramework,Version=v4.5.2 with Microsoft Forms. I am using a default json settings file to load the initial settings when the application starts. I am able to add TexTBox and NumericUpDown fields to my form to read and update values from the json file.

However, I have not found a way to update a TimeSpan value. I have tried using a TextBox and NumericUpDown and this will read the TimeSpan value and display the time in the form field. However, I am unable to update the TimeSpan value using the form field. I have also tried using DateTimePicker field (Formatted for just 24 hour time) in my form and this too will display the TimeSpan value but once again I am unable to edit the value using the datetime form field. For example, after changing the time from 03:00:00 to 04:00:00 the value will revert back to the default value as soon as you exit the field. I had this same behavior using both the TextBox and The DateTimePicker.

I have included the different code snippets for may application relating to the TimeSpan value. This value is setting the time to run a SQL backup.

this.TxtPickBackupStartTime.DataBindings.Add(
    nameof(this.TxtPickBackupStartTime.Text), applicationSettings,
    nameof(applicationSettings.StartBackupAt), false,
    DataSourceUpdateMode.OnValidation)

this.TxtPickBackupStartTime = new System.Windows.Forms.TextBox();

this.Controls.Add(this.TxtPickBackupStartTime);

private System.Windows.Forms.TextBox TxtPickBackupStartTime;

public TimeSpan StartBackupAt;

StartBackupAt = new TimeSpan(3, 0, 0),

settings.json file:
"StartBackupAt": "03:00:00",

enter image description here

I am currently getting the following error after implementing Oliver's suggestion below when replacing timeModelBindingSource with applicationSettings.StartBackupAt.

enter image description here

Any help would be greatly appreciated.

Joey

Below are the two parts are the code that I hope would provide additional information.

namespace TendBackupApplication.Forms
{
    public partial class SettingsDialog : Form
    {
        private readonly ApplicationSettings applicationSettings;

        public SettingsDialog(ApplicationSettings applicationSettings)
        {
            this.InitializeComponent();
            this.applicationSettings = applicationSettings;

            this.txtTime.DataBindings.Add(new Binding("Text", this.applicationSettings.StartBackupAt, "Time", true, DataSourceUpdateMode.OnValidation, "T"));

.

namespace TendBackupLibrary.Settings
{
    public delegate void ApplicationSettingsSavedEvent(object sender, EventArgs e);

    public class ApplicationSettings
    {
        private readonly SettingsReader settingsReader;
        private readonly SettingsFile defaultSettings;
        private SettingsFile previousSettings;
        private SettingsFile currentSettings;

        public ApplicationSettings(SettingsReader settingsReader)
        {
            this.settingsReader = settingsReader;
            this.defaultSettings = new SettingsFile
            {
                DatabaseName = "Tend",   
                StartBackupAt = new TimeSpan(03, 00, 00),
                BackupInterval = 10
                MaxDatabaseCopies = 1,
                MonitorInterval = 3, // seconds
                MaxMonitorFailures = 3,
                Enabled = true,

Here is the TimeSpan Function

public TimeSpan StartBackupAt
{
    get
    {
        return this.currentSettings.StartBackupAt;
    }
    set
    {
        this.currentSettings.StartBackupAt = value;
    }
}

settings.json file

"DatabaseName": "Tend",
  "StartBackupAt": "03:00:00",
  "BackupInterval": 10,
  "OverwriteDatabase": true,
  "MaxDatabaseCopies": 1,
  "MonitorInterval": 3,
  "MaxMonitorFailures": 3,
  "Enabled": true,
1

There are 1 best solutions below

9
Olivier Jacot-Descombes On

It works by binding the TextBox.Text property to a DateTime property of a model class. Just make sure to specify the T date/time format to suppress the display of the date part.

Example:

public class TimeModel
{
    public DateTime Time
    {
        get { return new DateTime(TimeSpan.Ticks); }
        set { TimeSpan = value.TimeOfDay; }
    }

    public TimeSpan TimeSpan { get; set; }
}
this.txtTime.DataBindings.Add(new System.Windows.Forms.Binding("Text",
     this.timeModelBindingSource, "Time", true,
     System.Windows.Forms.DataSourceUpdateMode.OnValidation, null, "T"));

Update

Now that I see the relevant parts of your code, I can more precise answer.

Add this property to your class

public DateTime StartBackupAtDateTime
{
    get { return new DateTime(StartBackupAt.Ticks); }
    set { StartBackupAt = value.TimeOfDay; }
}

Compile you app to make this new property visible to the binding mechanism.

Add a BindingSource component and a Data Source based on your ApplicationSettings class as described in WinForms – Bind controls to an object data source.

Delete any bindings from your textbox. Add a new binding to your TextBox as explained in the link. I.e., select your TextBox and in the properties window select (DataBindings) / (Advanced) and select your BindingSource component and StartBackupAtDateTime (instead of Name as the image in the link says) from the Binding drop-down. This does the DataBindings.Add thing automatically in the form.designer.cs file automatically.

All what remains to do is to assign the settings to the BindingSource:

// Replace bindingSource1 by the real name of your BindingSource.
bindingSource1.DataSource = applicationSettings;

Note that you must assign the whole settings object, not applicationSettings.StartBackupAtDateTime.

That's it.