Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

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

Posted on 2008-10-01
3
Medium Priority
?
566 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 30

Accepted Solution

by:
anarki_jimbel earned 2000 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 30

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

Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

Question has a verified solution.

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

Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…

688 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