Solved

Creating a Form With Mobile/Cell Phone Text Input Style Buttons

Posted on 2008-10-01
3
559 Views
Last Modified: 2013-12-17
I am just working on a small little idea and really need to make it more efficient, you will see why shortly.

Basically I am have 1 form, 3 textBoxes and 9 buttons.  Think of it as a mobile/cell phone when you text/send SMS.  You press the number a certain amount of times and you get a specific letter.

So any only 1 of the textboxes will be enabled at any one time, so there has to be a check to decide which to focus on to add the text - and I have no clue how to do that!.  Hopefully that gives an idea of what I'm trying to do.

My problem comes from the staggering, and mainly unnecessary amount of code what I have produces.  So I am hoping that somebody here can help me out.  You can see from the code below that for just 1 button it's a lot, so for 9 it would be far too big.  Especially as the code is only for 1 of the 3 textboxes.

private void btnKeyPad1_Click(object sender, EventArgs e)
        {
          
            if (txtFirstName.Enabled == true || txtSurName.Enabled == true || txtPIN.Enabled == true)
            {
                // some form of code to select whichever textbox and Focus() on it.   
                // I need to find out how to do this
             
                number1Count++;
                if (number1Count >= 4)
                {
                    number1Count = 1;
                }
                else if (number1Count == 1)
                {
                    textBox1.Text = textBox1.Text + "a";
                }
                else if (number1Count == 2)
                {
                    textBox1.Text = textBox1.Text + "b";
                }
                else if (number1Count == 3)
                {
                    textBox1.Text = textBox1.Text + "c";
                }
 
            }
        }

Open in new window

0
Comment
Question by:angus_young_acdc
  • 2
3 Comments
 
LVL 29

Accepted Solution

by:
anarki_jimbel earned 500 total points
ID: 22620400
The task you are talking about is a bit more tricky. At least here I can't see you using any timing. And with cellphone buttons you have to click a button three times in a specific time frame to print "c" (e.g.) into a textbox. How you do that?

How you detect what text box to print to?

Anyway, I have written simple application to achieve what you probably need. I use Timer class (win forms).

Notice: all button handlers are same except a char array.

So, add a timer to your application, set it's interval say to 50. Using this time you may adjust your response time.

The application has three textboxes with names you provided, buttons btnABC, btnDEF (add any more)., and a timer timer1. See the snippet
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace CellPhoneStyleTest
{
    public partial class Form1 : Form
    {
        // private variables
        private int clickCounter = 0;// how many time current button was clicked?
        private Button currentButton = null;// which letter button was clicked, "abc" or "def" or etc.
 
        private bool isTimerTicking = false;
        private int timerCount = 0;
        private int maxTimerCount = 10;
        private string currentChar = null;
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void btnABC_Click(object sender, EventArgs e)
        {
            char[] letterArray = { 'a', 'b', 'c' };// basicly, this should be the only different line for all buttons
            buttonClickHandler(sender, letterArray);
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (timerCount >= maxTimerCount)
            {
                isTimerTicking = false;
                currentButton = null;
                clickCounter = 0;
                timer1.Stop();
                timerCount = 0;
 
                // find what TextBox is Enabled and set current textbox object
                TextBox currentTextBox = null;
                if (txtFirstName.Enabled) { currentTextBox = txtFirstName; }
                else if (txtSurName.Enabled) { currentTextBox = txtSurName; }
                else if (txtPIN.Enabled) { currentTextBox = txtPIN; }
                else { MessageBox.Show("Error"); }
 
                currentTextBox.Text += currentChar;
            }
            else
            {
                isTimerTicking = true;
                timerCount += 1;
            }
        }
 
        private void btnDEF_Click(object sender, EventArgs e)
        {
            // just an example to have entire code here, not in a separate function
            if (isTimerTicking && (currentButton == (Button)sender)) // cast from sender object - code will be same for all buttons
            {
                this.clickCounter += 1;
            }
            else if (isTimerTicking && !(currentButton == (Button)sender))
            {
                timer1.Stop();
                timer1.Start();
                currentButton = (Button)sender;// set currentButton to this button
                this.clickCounter = 0;// it's clicked just one time
                currentChar = "";
            }
            else if (!isTimerTicking && currentButton == null)
            {
                timer1.Start();
                currentButton = (Button)sender;// set currentButton to this button
                this.clickCounter = 0;// it's clicked just one time
                currentChar = "";
            }
            else
            {
                MessageBox.Show("Error");
                return;
            }
 
 
 
            // we may click many time - so wrap around the letters
            char[] letterArray = { 'd', 'e', 'f' };// basicly, this should be the only different line for all buttons
            int currentCharIndex = this.clickCounter % letterArray.Length;
            currentChar = "" + letterArray[currentCharIndex];
        }
 
        private void buttonClickHandler(object sender, char[] letterArray)
        {
            if (isTimerTicking && (currentButton == (Button)sender)) // cast from sender object - code will be same for all buttons
            {
                this.clickCounter += 1;
            }
            else if (isTimerTicking && !(currentButton == (Button)sender))
            {
                timer1.Stop();
                timer1.Start();
                currentChar = ""; ;
                currentButton = (Button)sender;// set currentButton to this button
                this.clickCounter = 0;// it's clicked just one time
            }
            else if (!isTimerTicking && currentButton == null)
            {
                timer1.Start();
                currentButton = (Button)sender;// set currentButton to this button
                this.clickCounter = 0;// it's clicked just one time
                currentChar = "";
            }
            else
            {
                MessageBox.Show("Error");
                return;
            }
 
            // we may click many time - so wrap around the letters
            int currentCharIndex = this.clickCounter % letterArray.Length;
            currentChar = "" + letterArray[currentCharIndex];
        }
 
    }
}

Open in new window

0
 
LVL 15

Author Comment

by:angus_young_acdc
ID: 22622931
Hi there,

No I wasn't using any timing in that example, it was just a count so that if button1 was pressed twice the letter would be 'b'

---How you detect what text box to print to?
I have no idea, thats one of the many questions I am trying to find out the answer too.  I may just scrap this idea however - at least for now.

That code looks great, I will have a play with it now and see how I get on.  But that definately seems to cut down on the amount of useless code I have :)

I'm assuming that I could put the code below into one method and simply call that waiting for a true/false value in order to perform the action?

//Code inside the button for DEF
if (isTimerTicking && (currentButton == (Button)sender)) // cast from sender object - code will be same for all buttons
            {
                this.clickCounter += 1;
            }
            else if (isTimerTicking && !(currentButton == (Button)sender))
            {
                timer1.Stop();
                timer1.Start();
                currentButton = (Button)sender;// set currentButton to this button
                this.clickCounter = 0;// it's clicked just one time
                currentChar = "";
            }

Open in new window

0
 
LVL 29

Expert Comment

by:anarki_jimbel
ID: 22628539
Yes, you can put the code into one method and call it everywhere. That's was my intention - to write something "coding-saving" :)

By the way, I have fixed my buttonClickHandler. Basicly, I have added just one line ("timerCount = 0"), it will better simulate cellphone style behaviour. See the snippet.

About text fields. I don't know how you want to manage text fields. I just assume that just one field is enabled at the time, I select this enabled field, make to reference to it and enter text to it. Say, we have three fields, txtFirstname, txtSurName and txtPIN. txtSurname is enabled currently. Timer tick handler checks what text box is enabled:

                // find what TextBox is Enabled and set current textbox object
                TextBox currentTextBox = null;
                if (txtFirstName.Enabled) { currentTextBox = txtFirstName; }
                else if (txtSurName.Enabled) { currentTextBox = txtSurName; }
                else if (txtPIN.Enabled) { currentTextBox = txtPIN; }
                else { MessageBox.Show("Error"); }
 and enters a character into the currentTextBox.

' OK, how to enable-disable text boxes. What if you use another property, readonly? In this case you may use 'Enter' event to to set this property to false for a current box and true for others. And in the timer I have to check if the text box is NOT readonly to .

OK, check the updated snippet for entire form. Ask any questions. You need a timer on the form to get it working.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace CellPhoneStyleTest
{
    public partial class Form1 : Form
    {
        // private variables
        private int clickCounter = 0;// how many time current button was clicked?
        private Button currentButton = null;// which letter button was clicked, "abc" or "def" or etc.
 
        private bool isTimerTicking = false;
        private int timerCount = 0;
        private int maxTimerCount = 10;
        private string currentChar = null;
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void btnABC_Click(object sender, EventArgs e)
        {
            char[] letterArray = { 'a', 'b', 'c' };// basicly, this should be the only different line for all buttons
            buttonClickHandler(sender, letterArray);
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (timerCount >= maxTimerCount)
            {
                isTimerTicking = false;
                currentButton = null;
                clickCounter = 0;
                timer1.Stop();
                timerCount = 0;
 
                // find what TextBox is Enabled and set current textbox object
                TextBox currentTextBox = null;
                if (!txtFirstName.ReadOnly) { currentTextBox = txtFirstName; }
                else if (!txtSurName.ReadOnly) { currentTextBox = txtSurName; }
                else if (!txtPIN.ReadOnly) { currentTextBox = txtPIN; }
                else { MessageBox.Show("Error"); }
 
                currentTextBox.Text += currentChar;
            }
            else
            {
                isTimerTicking = true;
                timerCount += 1;
            }
        }
 
        private void btnDEF_Click(object sender, EventArgs e)
        {
            char[] letterArray = { 'd', 'e', 'f' };
            buttonClickHandler(sender, letterArray);
        }
 
        private void buttonClickHandler(object sender, char[] letterArray)
        {
            if (isTimerTicking && (currentButton == (Button)sender)) // cast from sender object - code will be same for all buttons
            {
                timerCount = 0;
                this.clickCounter += 1;
            }
            else if (isTimerTicking && !(currentButton == (Button)sender))
            {
                timer1.Stop();
                timer1.Start();
                currentChar = ""; ;
                currentButton = (Button)sender;// set currentButton to this button
                this.clickCounter = 0;// it's clicked just one time
            }
            else if (!isTimerTicking && currentButton == null)
            {
                timer1.Start();
                currentButton = (Button)sender;// set currentButton to this button
                this.clickCounter = 0;// it's clicked just one time
                currentChar = "";
            }
            else
            {
                MessageBox.Show("Error");
                return;
            }
 
            // we may click many time - so wrap around the letters
            int currentCharIndex = this.clickCounter % letterArray.Length;
            currentChar = "" + letterArray[currentCharIndex];
        }
 
        private void txtSurName_Enter(object sender, EventArgs e)
        {
            //System.Diagnostics.Debug.WriteLine("txtSurName_Enter");
            txtSurName.ReadOnly = false;
            txtFirstName.ReadOnly = true;
            txtPIN.ReadOnly = true;
        }
 
        private void txtFirstName_Enter(object sender, EventArgs e)
        {
            //System.Diagnostics.Debug.WriteLine("txtFirstName_Enter");
            txtSurName.ReadOnly =  true;
            txtFirstName.ReadOnly =false;
            txtPIN.ReadOnly = true;
 
        }
 
        private void txtPIN_Enter(object sender, EventArgs e)
        {
            //System.Diagnostics.Debug.WriteLine("txtPIN_Enter");
            txtSurName.ReadOnly = true;
            txtFirstName.ReadOnly = true;
            txtPIN.ReadOnly = false;
        }
 
    }
}

Open in new window

0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question