Search code examples
c#winformsmaskedtextbox

How can you write from right to left in a masked textbox?


I have a masked textbox that takes the hours as two digits from the user as input - hh. I am using the Form1_KeyPress event handler to enter the values into the textbox.

Currently, when you enter a value, for example, when you enter the digit 1, the textbox will show 1h. How can I set the masked textbox such that when you enter a value, it enters from the right hand side, for example, h1.

I have tried enabling the RightToLeft property for the control but this has had no effect on the behaviour.

private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (c == '\r' || c == '\t')
    {
        // Values entered
    }
    else
    {
        maskedTB.Select();
        maskedTB.Text += c;
    }

Code for entering values in masked textbox


Solution

  • Overview

    Note: The following is not a direct answer to the above question but, it is an alternative that I was able to use whilst meeting the requirements.

    The masked textbox kept giving me too many problems, so, I decided to use a normal textbox and implement the required functionality myself. The textbox was initialized with the text: hh:mm:ss.

    A method timeTextBox(char c, TextBox textbox) was written which would be called inside the KeyPress event handler. This method, would use a global int array, bufferArray, to store the non-formatted values for the time. For example, a time of 1 hour, 25 minutes, and 20 seconds, would be stored as 0,1,2,5,2,0. The string is initialized as all 0.

    Entering values

    When a key is pressed, the `IsDigit()` function is called to ensure only digits are entered. The whole array is then shifted by down by 1 (note, at the start the array only contains 0s so this does not have any effect) and the entered value is set at the final index of the buffer array. So, if the number `5` was pressed, the buffer array would contain `0,0,0,0,0,5`, and if the number 2 was pressed afterwards, the array would contain `0,0,0,0,5,2`, and so on.

    This array is then formatted in the format hh:mm:ss and is set as the text of the textbox.

    Removing values

    Removing a value when pressing backspace is very simple. You simply shift the array up by 1 and place a 0 at the 0th index of the buffer array. Then format as before and set the textbox text to the formatted string.

    Code

    int[] bufferArray = new int[6];
    private void Form1_KeyPress(object sender, KeyPressEventArgs e)
    {
        e.Handled = true;
        var c = e.KeyChar;
    
        if (textbox1.Focused)
            timeTextBox(c, textbox1);
    }
    
    private void timeTextBox(char c, TextBox textbox)
    {
        int finalIndex = bufferArray.Length - 1;
    
        string output = "";
    
        if (c == '\r' || c == '\t')
        {
            textbox.ReadOnly = true;    
            this.ActiveControl = null;  // Deselect all controls
        }
        else if (textbox.ReadOnly == false)
        {
            // Reset buffer if new textbox selected
            if (textbox.Text.Contains("hh"))
                bufferArray = new int[6];
    
            if (Char.IsDigit(c))
            {
                // Shift array down by 1
                for (int i = 0; i < bufferArray.Length - 1; i++)
                    bufferArray[i] = bufferArray[i + 1];
                bufferArray[finalIndex] = int.Parse(c.ToString());
    
                output = formatOutputString();
    
                textbox.Text = "";    // Clear textbox
                textbox.Text = string.Join("", output);  // Add values to textbox
            }
            else if (c == (char)Keys.Back)      // If backspace is pressed
            {
                // Shift array up by 1
                for (int i = bufferArray.Length - 1; i > 0; i--)
                    bufferArray[i] = bufferArray[i - 1];
                bufferArray[0] = 0;
    
                output = formatOutputString();
    
                textbox.Text = "";    // Clear textbox
                textbox.Text = string.Join("", output);  // Add values to textbox
            }
        }
    }
    
    private string formatOutputString()
    {
        string output = "";
    
        // Generate formated output string
        for (int i = 0; i < bufferArray.Length; i += 2)
        {
            output += $"{bufferArray[i]}{bufferArray[i + 1]}";
            if (i < bufferArray.Length - 2)
                output += ':';
        }
    
        return output;
    }