Solved

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

Posted on 2008-10-01
3
555 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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

706 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now