Hello guys, im stuck working on a simulation program. I am working on a program which mimics a door's security key panel. In case if you have been wondering what a door's security key panel is.. its a keypad on the door which unlocks the door upon entering a proper password (in this case a combination of 0-9 and * & # symbols.

I've created a form and added 12 buttons on it. Whose Text reads 1,2,3,4,5,6,7,8,9,*,0,#. Also I have added a picture box whose default image is a black image. Now according to my simulation, all I need is to enter a 4 character password and if i enter the password right, the picture box's image would change (to green if correct or red if wrong password resp.)

I dont know how you professionals do it. But I have come up with an idea of mine to capture the sequence of key presses.

this is how I do it:

on click() event on every button, I assign a value of the button respective to the text of the button pressed.

for eg: lets assume button1 has its Text "1, and button2 has its Text "2"... so its event would be something like..

private value;

private void button1_click(object sender, EventArgs e)
{
     value ="1";
}

private void button2_click(object sender, EventArgs e)
{
     value ="2";
}

private void button3_click(object sender, EventArgs e)
{
     value ="3";
}

and so on..

I made a custom function which saves the key presses in an ArrayList

private ArrayList myList = new ArrayList(3);
   private void captureData(string content)
   {
           myList.Add(content);
   }

now that this function adds data to an ArrayList, i need to feed data into this ArrayList. So I modify my button events to the following:

private value;

private void button1_click(object sender, EventArgs e)
{
     value ="1";
     if(myList.Capacity<=3)
     {
         captureData(value);
     }
     else
     {
         // do something else
     }
}

private void button2_click(object sender, EventArgs e)
{
     value ="2";
     if(myList.Capacity<=3)
     {
         captureData(value);
     }
     else
     {
         // do something else
     }

}

private void button3_click(object sender, EventArgs e)
{
     value ="3";
     if(myList.Capacity<=3)
     {
         captureData(value);
     }
     else
     {
         // do something else
     }

}

and so on... so far so good..

now my problem starts here.

1. I have included a If construct on the buttons to check the number of characters the user pressed. I need it to limit it to 4. How do I do that? Ive tried changing array size and changed the <=3 to 2 and 4; it didnt help. MY LOGIC FAILS ME HERE.

2. ALSO im trying to include a compare function in else part of the button which invokes a function as soon as the user presses and releases the 4th part of the password. How do I do that?


any help here would be greatly appreciated..

Thanks for your time.
cheers!

Comments
Well documented question!

myList.Capacity is the maximum items allowed in the list. Because lists are dynamic this will change as items are added.
What you need to test is myList.Count which is the number of items in the list.

Edited 6 Years Ago by nick.crane: n/a

hello nick, thanks for the prompt reply. I have replaced the code and it works fine now.

i still need a bit of help here.. In my constructor, I have a custom function something like this:

private ArrayList passList = new ArrayList(3);
        public Form1()
        {
            InitializeComponent();
            passList.Capacity = 0;
            authorize();
        }

where the code unfolds to

private void authorize()
        {
            int i = 0;
            StreamReader srobj = new StreamReader("C:\\Users\\dw104\\Desktop\\myfile.txt");
            for (i = 0; i < 3; i++)
            {
                passList.Add((char)srobj.Read());
            }
        }

the above method authorize reads content of a file myfile.txt character by character and dumps it into an arraylist. and as its being called in the constructor, the dumping of data begins on program execution (which means my password will be read from file on program start).

now I have an arraylist (as mentioned earlier in previous post) filled with user input. all I have to do now is to compare the data of the both array lists. This is how I intend to do it.

private bool compare(ArrayList userInput, ArrayList db)
        {
            foreach (object i in userInput)
            {
                foreach (object j in db)
                {
                    if (i.Equals(j))
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            return false;
        }

however I feel I am doing something really stupid here, and I dont know what it is. Is this the right way to do the things?

also, in my previous post. Is there an alternative and efficient method of writing the code instead of the one I used?.

any more help will be appreciated :)

cheers!

however I feel I am doing something really stupid here, and I dont know what it is. Is this the right way to do the things?

The comparison should test each key value in turn. You should be using a basic for not a foreach .

for(i = 0; i < 4; i++)
{
    if (!userInput(i).Equals(db(i)))
    {
        return false;
    }
}
return true;

also, in my previous post. Is there an alternative and efficient method of writing the code instead of the one I used?.

There are lots of (better:icon_question:) ways to do some of the things you are doing, but what you are doing is not wrong. There is always another way to do something in programming. Sometimes it is down to a programmer's own personal feeling which methods are used. :)

Some ideas for you to consider:

Personally, I would store the entered password in a string and read the required password to a string. This would make the comparison easier.

Or, since the buttons represent numbers, I might use an integer.

One thing I would do is to have a common button event handler.
See [POST=1252373]this post[/POST] for how to attach to an existing event handler.

The sender parameter in the event handler points to the Button object that called the event; which is how you can identify which button was pressed. Cast sender to a Button to read the button's properties.

value += ((System.Windows.Forms.Button)sender).Text;
Comments
Have to agree :)
Good thoughts

value += ((System.Windows.Forms.Button)sender).Text;

Agree with you Nick, all roads lead to Rome
This would be my way:

Button MyButton = sender as Button;
value += MyButton.Text;

I dont get this concept of utilizing same event handler.. maybe I must do some research on it before i can actually use it. but for now I will do this my way and change it later when I do understand what actually is happening.
--

nick, do you suggest me to validate password as soon as the user enters? wouldn't that be complex to implement? the only way I can think of to achieve it is to using some kind of observer to keep a count of button clicks made and limit the clicks to 4. is there an alternative that you can think of?

I have removed ArrayList as a whole and am working with strings now. the following is my code

{
        private string buttoncontent;
        private string userPass = null;
        private int click = 3;
        private string dbPass = null;

        public Form1()
        {
            InitializeComponent();
            authorize();
        }

and the buttons are

private void button1_Click(object sender, EventArgs e)
        {
            buttoncontent = button1.Text;
            if (click > 0)
            {
                processInput(buttoncontent);
            }
            else
            {
                check();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            buttoncontent = button2.Text;
            if (click > 0)
            {
                processInput(buttoncontent);
            }
            else
            {
                check()
            }
        }

and so on for different buttons...

private void authorize()
        {
            StreamReader sr = new StreamReader("C:\\Users\\dw104\\Desktop\\myfile.txt");
            dbPass = sr.ReadLine();
        }

        private void processInput(string value)
        {
            userPass += value;
            click--;
        }

and this is where the checking takes place. I have tested this code on a console application which works perfectly without any problems.

private void check()
        {
            if (userPass.ToString().Equals(dbPass.ToString()))
            {
                MessageBox.Show("Access Granted");
            }
            else
            {
                MessageBox.Show("Access Denied");
            }
        }

I wrote this code to replace my older one with array list. the problem with this code is that I used a counter called click whose default value is 4 and each times the user click a button, the value of click becomes 0; i.e, i need to make the user click 4 buttons and when he clicks the 4th button, i need a message box pop out displaying a result (access granted or denied). i havent been able to figure out how to do it, i know its simple math, but im so confused to find the error out. im guessing it has something to do with assignment of click and its comparisions.

p.s.: yes the comparision works fine only after the 5th button is clicked. it gives me proper result.

What you are doing looks fine.

Some things to consider:
Most key-code systems that I know of require an Enter key to confirm code entry. This would simplify your number button code as the Check function would only be done in the Enter key Click event handler and you would no longer need the click counter.
You might like to consider is a cancel button to allow the user to clear the entry on error.

Regarding Button Click event handling
button1 is clicked, Click event fires, button1_Click method called with sender parameter set to button1.
button2 is clicked, Click event fires, button2_Click method called with sender parameter set to button2.
and so on for button3, button4, etc.

If each of these buttons has a different function then this is fine.
If each of them does the same thing then there is a lot of duplicate code.
To have more easily maintained code it is possible to link(attach) each button's Click event to the same method. But if we do this how do we know which button was pressed? Well this is where the sender parameter comes in. We can convert sender to the correct type (using a cast or as) and access the control properties.

When using a common event method we get
button1 is clicked, Click event fires, button_Click method called with sender parameter set to button1.
button2 is clicked, Click event fires, button_Click method called with sender parameter set to button2.
and so on for button3, button4, etc.

As you know, when you double click on a button a button1_Click method is automatically added to your forms code.
The forms designer also adds code to Forms1.desinger.cs file to link this method to the Button.Click event.

The easiest way to set the same method for several events is using the Events list found in the Properties window. (See my earlier post for a link on how to do this.)

Edited 6 Years Ago by nick.crane: n/a

hey guys thanks for your massive help.
thanks to you guys I could finish this simple demo finally.

and here's my 100% working code

Form1.Designer.cs file:

namespace DD
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.button3 = new System.Windows.Forms.Button();
            this.button4 = new System.Windows.Forms.Button();
            this.button5 = new System.Windows.Forms.Button();
            this.button6 = new System.Windows.Forms.Button();
            this.button7 = new System.Windows.Forms.Button();
            this.button8 = new System.Windows.Forms.Button();
            this.button9 = new System.Windows.Forms.Button();
            this.button10 = new System.Windows.Forms.Button();
            this.button11 = new System.Windows.Forms.Button();
            this.button12 = new System.Windows.Forms.Button();
            this.signal = new System.Windows.Forms.PictureBox();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            ((System.ComponentModel.ISupportInitialize)(this.signal)).BeginInit();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(12, 12);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(50, 50);
            this.button1.TabIndex = 0;
            this.button1.Text = "1";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button_Click);
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(68, 12);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(50, 50);
            this.button2.TabIndex = 1;
            this.button2.Text = "2";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button_Click);
            // 
            // button3
            // 
            this.button3.Location = new System.Drawing.Point(125, 12);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(50, 50);
            this.button3.TabIndex = 2;
            this.button3.Text = "3";
            this.button3.UseVisualStyleBackColor = true;
            this.button3.Click += new System.EventHandler(this.button_Click);
            // 
            // button4
            // 
            this.button4.Location = new System.Drawing.Point(12, 68);
            this.button4.Name = "button4";
            this.button4.Size = new System.Drawing.Size(50, 50);
            this.button4.TabIndex = 3;
            this.button4.Text = "4";
            this.button4.UseVisualStyleBackColor = true;
            this.button4.Click += new System.EventHandler(this.button_Click);
            // 
            // button5
            // 
            this.button5.Location = new System.Drawing.Point(68, 68);
            this.button5.Name = "button5";
            this.button5.Size = new System.Drawing.Size(50, 50);
            this.button5.TabIndex = 4;
            this.button5.Text = "5";
            this.button5.UseVisualStyleBackColor = true;
            this.button5.Click += new System.EventHandler(this.button_Click);
            // 
            // button6
            // 
            this.button6.Location = new System.Drawing.Point(125, 68);
            this.button6.Name = "button6";
            this.button6.Size = new System.Drawing.Size(50, 50);
            this.button6.TabIndex = 5;
            this.button6.Text = "6";
            this.button6.UseVisualStyleBackColor = true;
            this.button6.Click += new System.EventHandler(this.button_Click);
            // 
            // button7
            // 
            this.button7.Location = new System.Drawing.Point(12, 124);
            this.button7.Name = "button7";
            this.button7.Size = new System.Drawing.Size(50, 50);
            this.button7.TabIndex = 6;
            this.button7.Text = "7";
            this.button7.UseVisualStyleBackColor = true;
            this.button7.Click += new System.EventHandler(this.button_Click);
            // 
            // button8
            // 
            this.button8.Location = new System.Drawing.Point(68, 124);
            this.button8.Name = "button8";
            this.button8.Size = new System.Drawing.Size(50, 50);
            this.button8.TabIndex = 7;
            this.button8.Text = "8";
            this.button8.UseVisualStyleBackColor = true;
            this.button8.Click += new System.EventHandler(this.button_Click);
            // 
            // button9
            // 
            this.button9.Location = new System.Drawing.Point(125, 124);
            this.button9.Name = "button9";
            this.button9.Size = new System.Drawing.Size(50, 50);
            this.button9.TabIndex = 8;
            this.button9.Text = "9";
            this.button9.UseVisualStyleBackColor = true;
            this.button9.Click += new System.EventHandler(this.button_Click);
            // 
            // button10
            // 
            this.button10.Location = new System.Drawing.Point(12, 180);
            this.button10.Name = "button10";
            this.button10.Size = new System.Drawing.Size(50, 50);
            this.button10.TabIndex = 9;
            this.button10.Text = "*";
            this.button10.UseVisualStyleBackColor = true;
            this.button10.Click += new System.EventHandler(this.button_Click);
            // 
            // button11
            // 
            this.button11.Location = new System.Drawing.Point(68, 180);
            this.button11.Name = "button11";
            this.button11.Size = new System.Drawing.Size(50, 50);
            this.button11.TabIndex = 10;
            this.button11.Text = "0";
            this.button11.UseVisualStyleBackColor = true;
            this.button11.Click += new System.EventHandler(this.button_Click);
            // 
            // button12
            // 
            this.button12.Location = new System.Drawing.Point(125, 180);
            this.button12.Name = "button12";
            this.button12.Size = new System.Drawing.Size(50, 50);
            this.button12.TabIndex = 11;
            this.button12.Text = "#";
            this.button12.UseVisualStyleBackColor = true;
            this.button12.Click += new System.EventHandler(this.button_Click);
            // 
            // signal
            // 
            this.signal.Image = global::UniKEY.Properties.Resources.wait;
            this.signal.Location = new System.Drawing.Point(68, 236);
            this.signal.Name = "signal";
            this.signal.Size = new System.Drawing.Size(50, 25);
            this.signal.TabIndex = 12;
            this.signal.TabStop = false;
            // 
            // timer1
            // 
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(189, 274);
            this.Controls.Add(this.signal);
            this.Controls.Add(this.button12);
            this.Controls.Add(this.button11);
            this.Controls.Add(this.button10);
            this.Controls.Add(this.button9);
            this.Controls.Add(this.button8);
            this.Controls.Add(this.button7);
            this.Controls.Add(this.button6);
            this.Controls.Add(this.button5);
            this.Controls.Add(this.button4);
            this.Controls.Add(this.button3);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
            this.Name = "Form1";
            this.Text = "Door Demo";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.signal)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.Button button3;
        private System.Windows.Forms.Button button4;
        private System.Windows.Forms.Button button5;
        private System.Windows.Forms.Button button6;
        private System.Windows.Forms.Button button7;
        private System.Windows.Forms.Button button8;
        private System.Windows.Forms.Button button9;
        private System.Windows.Forms.Button button10;
        private System.Windows.Forms.Button button11;
        private System.Windows.Forms.Button button12; 

        private System.Windows.Forms.PictureBox signal;
        private System.Windows.Forms.Timer timer1;
    }
}

Form1.cs code

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;
using System.Collections;
using System.IO;

namespace DD
{
    public partial class Form1 : Form
    {
        private string buttoncontent;
        private string userPass = null;
        private int click;
        private string dbPass = null;

        public Form1()
        {
            click = 0;
            InitializeComponent();
            authorize();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void reportError()
        {
            MessageBox.Show("Error Occoured!");
        }

        private void button_Click(object sender, EventArgs e)
        {
            buttoncontent = ((System.Windows.Forms.Button)sender).Text;
            if (click < 3)
            {
                processInput(buttoncontent);
            }
            else if (click == 3)
            {
                processInput(buttoncontent);
                check();
            }
            else
            {
                reportError();
            }
        }

        private void authorize()
        {
            StreamReader sr = new StreamReader("C:\\Users\\dw104\\Desktop\\myfile.txt");
            dbPass = sr.ReadLine();
        }

        private void processInput(string value)
        {
            if (click == 0)
            {
                userPass = value;
                click++;
            }
            else if (click > 0)
            {
                userPass += value;
                click++;
            }
        }

        private void check()
        {
            if (userPass.ToString().Equals(dbPass.ToString()))
            {
                click = 0;
                authorise_user();
            }
            else
            {
                click = 0;
                deauthorise_user();
            }
        }

        private void authorise_user()
        {
            signal.Image = Image.FromFile("C:\\Users\\dw104\\Desktop\\go.jpg");
            resetSignal();
            freezePad();
        }
        private void deauthorise_user()
        {
            signal.Image = Image.FromFile("C:\\Users\\dw104\\Desktop\\stop.jpg");
            resetSignal();
            freezePad();
        }

        private void freezePad()
        {
            button1.Enabled = false;
            button2.Enabled = false;
            button3.Enabled = false;
            button4.Enabled = false;
            button5.Enabled = false;
            button6.Enabled = false;
            button7.Enabled = false;
            button8.Enabled = false;
            button9.Enabled = false;
            button10.Enabled = false;
            button11.Enabled = false;
            button12.Enabled = false;
        }

        private void unfreezePad()
        {
            button1.Enabled = true;
            button2.Enabled = true;
            button3.Enabled = true;
            button4.Enabled = true;
            button5.Enabled = true;
            button6.Enabled = true;
            button7.Enabled = true;
            button8.Enabled = true;
            button9.Enabled = true;
            button10.Enabled = true;
            button11.Enabled = true;
            button12.Enabled = true;
        }

        private void resetSignal()
        {
            timer1.Enabled = true;
            timer1.Interval =5000;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            unfreezePad();
            signal.Image = Image.FromFile("C:\\Users\\dw104\\Desktop\\wait.jpg");
            timer1.Enabled = false;
        }
    }
}

some of you might find this code "low tech", yeah Its not optimized, and I think there is a better way to write this program.

If there is one please do let me know about it.

there is one more thing.. I have learnt that using a design pattern called state pattern, this code could be used efficiently and would save a lot of time and resources.

can someone tell me how could a state pattern be used in this application?

with best regards,
emc

Glad to help. :)

There does not seem to be multiple states in your app to justify a state patern method. Perhaps in the wider app to which this keypad provides authorisation you could implement an authorised state and an unauthorised state.

Please remember to mark your thread solved if the issue has been resolved.

I really want to do this using state pattern as to develop my understanding in patterns.

I will then divide the application into 3 states. ready/stop/go.

-ready would display black color.
-stop would display red color.
-go would display green color.

now I have made an interface called state.
i have a method declaration in it.
i then have 3 different classes implementing the method and having the same method.
the method just returns path of the image.

on form_load i'll call up ready method (not sure how) which would display ready image on form. and when authentication occurs, i would then call up respective methods which would change the image respectively and then return back to ready state with ready image.

any ideas how to do it?

As this is really a new topic and perhaps something that others might be interested in, can I suggest that you start a new thread. (And mark this one solved.)

Edited 6 Years Ago by nick.crane: n/a

This question has already been answered. Start a new discussion instead.