I am using Visual Studio 2008.

What i am trying to accomplish is a textbox
default data: ABCDEFGHIJKLMOP

textbox.maxlength = 16
textbox.charactercasing = upper

Now the trick is only the letters A-P can be allowed
the string has to be 16 chars long.
I would love to figure out a way to to some sort of insert over method so when you go to the textbox only one char is highlighted at a time to change for example "A" would be highlight then press the right arrow key then "B" would be highlighted which you could change to any char A-P without changing the rest of the string. so you always have 16 chars.

I would appreciate any thoughts on where to research more on accomplishing this or snippets of code to play with.

Thank you

Perhaps you could change this to what you need.

Here is what i came up with.. it should get you started

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace daniweb
{
  public partial class frmFunnyTextBox : Form
  {
    volatile bool mouseDown;

    public frmFunnyTextBox()
    {
      InitializeComponent();
      mouseDown = default(bool);
    }

    private void frmFunnyTextBox_Load(object sender, EventArgs e)
    {
      textBox1.Text = "ABCDEFGHIJKLMNOP";
      textBox1.MaxLength = 16;
    }

    private void button1_Click(object sender, EventArgs e)
    {
      System.Diagnostics.Debugger.Break();
    }

    private static bool ValidChar(char testChar)
    {
      return (char.ToUpper(testChar) >= 'A' && char.ToUpper(testChar) <= 'P');
    }

    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
      if (!ValidChar((char)e.KeyCode) || mouseDown)
        e.Handled = true;
    }
    

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
      if (ValidChar(e.KeyChar))
      {
        int idx = textBox1.SelectionStart;
        textBox1.SelectedText = Convert.ToString(e.KeyChar);
        idx++;
        if (idx >= textBox1.Text.Length)
          idx = 0;

        textBox1.Select(idx, 1);
      }
      e.Handled = true;
    }

    private void textBox1_Enter(object sender, EventArgs e)
    {
      textBox1.Select(0, 1);
    }

    private void textBox1_MouseDown(object sender, MouseEventArgs e)
    {
      mouseDown = true;
    }

    private void textBox1_MouseUp(object sender, MouseEventArgs e)
    {
      mouseDown = false;
      if (textBox1.SelectionLength > 1)
        textBox1.SelectionLength = 1;
    }

    private void textBox1_MouseClick(object sender, MouseEventArgs e)
    {
      textBox1.Select(textBox1.SelectionStart, 1);
    }

    private void textBox1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
      textBox1.Select(0, 1);
    }

    private void textBox1_MouseMove(object sender, MouseEventArgs e)
    {
      if (e.Button == MouseButtons.Left)
        textBox1.SelectionLength = 1;
    }

  }
}

You have like 209384029384 scenarios to handle here:
* Delete Key
* Backspace
* Highlighting 10 characters and typing one, which will delete the other 9
* Double clicking and highlighting all
* Pasting
* Cutting

...probably more

I appreciate the quick answers..

I realize i have many variables to cover but was looking for a jumping point for main problems i could not find reference to on my Internet searches.

I had found out how to limit it to only letters using If e.KeyChar Like "[A-z]" Then e.Handled = False however was not sure how to limit it further to only A-P.

The insert method was something i could not figure how to even start

I will keep yall informed as to the solution i find if for no other reason to help someone else with a similar problem.

If you attach (wire) the following key events to your control, it will limit the chars to uppercase A thru P. You can also modify this code to convert lower chars to upper if you wish.

// uses boolean set in KeyDown event to determine whether this was an allowed character pressed
        private void textBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            // Check for the flag being set in the KeyDown event.
            if (!charAllowed)
            {
                // Stop the character from being entered into the control
                e.Handled = true;
            }
            else if (e.KeyChar < 'A' || e.KeyChar > 'P')
                e.Handled = true;
        }

        // Used to set flag to stop specific charactrs from entry into our control
        // Works in conjunction our KeyPress event handler.
        private void textBox_KeyDown(object sender, KeyEventArgs e)
        {
            // Initialize the flag.
            charAllowed = true;

            // Determine whether the keystroke is allowed
            // Exclude those with the following modifiers
            if (Control.ModifierKeys == Keys.Control ||
                Control.ModifierKeys == Keys.Alt)
            {
                charAllowed = false;
            }
        }

Check out the String.Length property to see how you can determine the number of characters already entered, then see if you can figure out where to put it in the code I gave you to prevent more than 16 being entered--good luck.

Thank you
will try and let yall know

If you pursue your customized editing (overwrite mode with char highlighting of caret position), you will need to manipulate how the control functions by checking the cursor/caret position.

You can use the TextBox.CaretIndex property to determine and set position.

You can use the TextBox.Select method to highlight/select the character at the current position.

Most programmers would create a custom control to do all of the things you are trying to achieve, but this sounds like a homework assignment you have decided to enhance even further. If so, kudos for your curiosity and extra effort!

Appreciate all the help

But alas it is not homework it is all curiosity to see if i can accomplish it

If I can accomplish it by writing a custom control I may research that as well.

I have this weekend open so I will see what i can accomplish

Thanks everyone I shall keep you all posted on my progress.

I appreciate the quick answers..

I realize i have many variables to cover but was looking for a jumping point for main problems i could not find reference to on my Internet searches.

I had found out how to limit it to only letters using If e.KeyChar Like "[A-z]" Then e.Handled = False however was not sure how to limit it further to only A-P.

The insert method was something i could not figure how to even start

I will keep yall informed as to the solution i find if for no other reason to help someone else with a similar problem.

I don't understand. The code I posted did limit characters to A-P and stopped a user from hitting backspace or delete. Did you even try the code?

see below, i also attach the working solution to this post

Form1.cs :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace RestrictedInputTextbox
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}
		List<char> wantedChars = new List<char>(new char[] { 'A', 'B', 'C','D','E','F','G','H','I','J','K','L','M','O','P' });
		private void textBox1_TextChanged(object sender, EventArgs e)
		{
			foreach (char c in textBox1.Text.ToCharArray())
			{
				if (wantedChars.IndexOf(c) == -1)
				{
					MessageBox.Show(c.ToString() + " invalid character");
					break;
				}
			}

		}
	}
}

Sknake,

Yes and i pointed out that i hadn't known how to do that before your post in the forum.

Between you and the research i am doing that part of the equation is figured out

the main issue i am left with is the insert option i spoke of earlier which was not addressed in your code.

I am still researching this and playing around with my code however I see DoubleD's suggestion of the the caret Index or just creating a single custom control to accomplish it all to be the only two viable options so far to accomplish this.

I see DoubleD's suggestion of the the caret Index or just creating a single custom control to accomplish it all to be the only two viable options so far to accomplish this.

Unfortunately, I lied about the CaretIndex property.:icon_redface:
That exists only for .ASPX code, which also uses C#--don't ask me why they didn't extend the functionality.

Anyway, here are a couple of methods that should accomplish the manipulation you described:

static int GetCaretPos(TextBox tbx)
        {
            return tbx.SelectionStart; // current position (won't work for you if user has selected some text)
        }
        static void SelectCharAtPos(TextBox tbx, int pos)
        {
            tbx.Select(pos, 1); // select one char beginning at pos
        }

However, you are really opening a can of worms when you begin to implement the behavior you described because: What happens if the user tries to select any portion of the text manually?--etc. I used to create controls to do funky stuff for clients years ago in WinAPI, which I could probably dig up, but do you really want to go to all this trouble?

After playing around on this problem most of the weekend I decided to go a slightly easier route:

I kept the textbox.charactercasing set to upper
and textbox.maxlength set to 16

I revised portions of sknake's code to accomplish the limiting of chars to A-P

Instead of an insert over option I spoke of I set a validation code to make sure the textbox had 16 chars in it or it would pop up a messagebox alerting the user that the field must be filled in full.

I will still play with this at a later date but for the time I am happy with the outcome. Again thank you all especially sknake and DdoubleD for your time.

Further testing of all of sknake's code reveals he did accomplish this

Kudos mate, Reputation points have been awarded to you my friend.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.