our notes for our youngers

December 9, 2009

Shooting Game ေလးေရးရေအာင္ – 2

pic1

pic1

download source window apppication here


http://www.mediafire.com/download.php?kyndziv3ijv

ကြၽန္ေတာ္ Exercise Two အေနနဲ႔ ေပးခဲ႔တဲ႔ ေသနတ္ပစ္တဲ႔ game ေလးပါ။ ကြၽန္ေတာ္ video tutorial အေနနဲ႔ လုပ္ေပးခ်င္ေပမယ့္ မိုးကုန္သြားျပီဆိုေတာ့ မီးက အခြင့္အေရး မေပးေတာ့ဘူးဗ်ာ။ ဒါေၾကာင့္ ကုဒ္ေလးကိုပဲ ျမန္ျမန္ကူးလာျပီး တင္ေပးလိုက္ပါတယ္။ ညီတို႔ Program ကို Run ျပီး Code ကို Trace လိုက္ၾကည့္လိုက္ရင္ နားလည္မွာပါ။ မရွင္းတဲ႔ အပိုင္းေလးေတြကို ေကာမန္႔မွာ ျပန္ေမးပါ။ ကြၽန္ေတာ္ ျပန္ရွင္းျပပါ့မယ္။ ေနာက္ထပ္ exercise three အေနနဲ႔ေရာ ဘာေရးရင္ ေကာင္းမလဲ… အၾကံရွိရင္လည္း ေကာ္မန္႔ေပးခဲ႔ၾကပါဦး။

public partial class Form1 : Form
{
    int startCounter = 6;
    int bulletCount = 7;
    int totalPoint = 0;
    int currentPoint = 0;
    int tmr = 0;
    bool PlayingTime = false;
    bool bulletMovingTime = false;
    Random rnd = new Random();

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyValue == 113 && !PlayingTime)
        {
            StartGame();
        }
        else if (PlayingTime)
        {
            if (e.KeyValue == 38)
            {
                if (picGun.Top > groupBox1.Height + groupBox1.Top)
                {
                    picGun.Top -= 5;
                    if (!bulletMovingTime)
                    {
                        picMovingBullet.Top -= 5;
                    }
                }
            }
            else if (e.KeyValue == 40)
            {
                if (picGun.Top + picGun.Height < panel1.Top)                 {                     picGun.Top += 5;                     if (!bulletMovingTime)                     {                         picMovingBullet.Top += 5;                     }                 }             }             else if (e.KeyValue == 13 || e.KeyValue == 32)             {                 if (!bulletMovingTime)                 {                     if (bulletCount >= 1)
                    {
                        bulletCount--;
                        lblTotalBullet.Text = bulletCount.ToString();
                        totalPoint += Convert.ToInt32(lblTarget.Text);
                        bulletMovingTime = true;
                        tmrMovingBullet.Enabled = true;
                        picMovingBullet.Left = picGun.Left + picGun.Width;
                        picMovingBullet.Top = picGun.Top + 3;
                        switch (bulletCount)
                        {
                            case 1: picBullet1.Visible = true;
                                picBullet2.Visible = false;
                                picBullet3.Visible = false;
                                picBullet4.Visible = false;
                                picBullet5.Visible = false;
                                picBullet6.Visible = false;
                                picBullet7.Visible = false;
                                break;
                            case 2: picBullet1.Visible = true;
                                picBullet2.Visible = true;
                                picBullet3.Visible = false;
                                picBullet4.Visible = false;
                                picBullet5.Visible = false;
                                picBullet6.Visible = false;
                                picBullet7.Visible = false;
                                break;
                            case 3: picBullet1.Visible = true;
                                picBullet2.Visible = true;
                                picBullet3.Visible = true;
                                picBullet4.Visible = false;
                                picBullet5.Visible = false;
                                picBullet6.Visible = false;
                                picBullet7.Visible = false;
                                break;
                            case 4: picBullet1.Visible = true;
                                picBullet2.Visible = true;
                                picBullet3.Visible = true;
                                picBullet4.Visible = true;
                                picBullet5.Visible = false;
                                picBullet6.Visible = false;
                                picBullet7.Visible = false;
                                break;
                            case 5: picBullet1.Visible = true;
                                picBullet2.Visible = true;
                                picBullet3.Visible = true;
                                picBullet4.Visible = true;
                                picBullet5.Visible = true;
                                picBullet6.Visible = false;
                                picBullet7.Visible = false;
                                break;
                            case 6: picBullet1.Visible = true;
                                picBullet2.Visible = true;
                                picBullet3.Visible = true;
                                picBullet4.Visible = true;
                                picBullet5.Visible = true;
                                picBullet6.Visible = true;
                                picBullet7.Visible = false;
                                break;
                            case 7: picBullet1.Visible = true;
                                picBullet2.Visible = true;
                                picBullet3.Visible = true;
                                picBullet4.Visible = true;
                                picBullet5.Visible = true;
                                picBullet6.Visible = true;
                                picBullet7.Visible = true;
                                break;
                            default: picBullet1.Visible = false;
                                picBullet2.Visible = false;
                                picBullet3.Visible = false;
                                picBullet4.Visible = false;
                                picBullet5.Visible = false;
                                picBullet6.Visible = false;
                                picBullet7.Visible = false;
                                break;
                        }
                    }
                    else
                    {
                        tmrMovingTarget.Enabled = false;
                    }
                }
            }
        }
    }

    private void tmrTimer_Tick(object sender, EventArgs e)
    {
        tmr++;
        lblTimer.Text = tmr.ToString("D4");
        if (currentPoint != 0 && totalPoint != 0)
        {
            decimal accuracy = ((Convert.ToDecimal(currentPoint) / Convert.ToDecimal(totalPoint)) * 100);
            lblAccuracy.Text = Math.Round(accuracy).ToString("N0") + "%";
            lblPoint.Text = currentPoint + "/" + totalPoint;
        }
    }

    private void tmrMovingTarget_Tick(object sender, EventArgs e)
    {
        lblTarget.Top = rnd.Next(groupBox1.Height + groupBox1.Top, panel1.Top - lblTarget.Height);
        lblTarget.Text = Convert.ToString(rnd.Next(1, 6) * 2 - 1);
    }

    private void tmrStartCounter_Tick(object sender, EventArgs e)
    {
        if (startCounter == 6)
        {
            lblReady.Text = "Ready to start";
            startCounter--;
        }
        else if (startCounter >= 1)
        {
            lblReady.Text = (startCounter--).ToString();
        }
        else if (startCounter == 0)
        {
            lblReady.Text = "GO!";
            startCounter--;
        }
        else
        {
            PlayingTime = true;
            tmrMovingTarget.Enabled = true;
            tmrStartCounter.Enabled = false;
            lblReady.Visible = false;
            tmrTimer.Enabled = true;
        }
    }

    private void tmrMovingBullet_Tick(object sender, EventArgs e)
    {
        if (picMovingBullet.Left + picMovingBullet.Width >= this.ClientSize.Width)
        {
            tmrMovingBullet.Enabled = false;
            bulletMovingTime = false;
            picMovingBullet.Left = picGun.Left + picGun.Width;
            picMovingBullet.Top = picGun.Top + 3;
            ShowMessage();
        }
        else if ((picMovingBullet.Left + picMovingBullet.Height >= lblTarget.Left) &&
            (picMovingBullet.Top + picMovingBullet.Height > lblTarget.Top && picMovingBullet.Top < lblTarget.Top + lblTarget.Height))
        {
            currentPoint += Convert.ToInt32(lblTarget.Text);
            lblPoint.Text = currentPoint + "/" + totalPoint;
            tmrMovingBullet.Enabled = false;
            bulletMovingTime = false;
            picMovingBullet.Left = picGun.Left + picGun.Width;
            picMovingBullet.Top = picGun.Top + 3;
            ShowMessage();
        }
        else
            picMovingBullet.Left += 3;
    }

    private void ShowMessage()
    {
        if (bulletCount == 0)
        {
            tmrMovingTarget.Enabled = false;
            tmrTimer.Enabled = false;
            lblPoint.Text = currentPoint + "/" + totalPoint;
            PlayingTime = false;
            decimal accuracy = ((Convert.ToDecimal(currentPoint) / Convert.ToDecimal(totalPoint)) * 100);
            lblAccuracy.Text = Math.Round(accuracy).ToString("N0") + "%";
            MessageBox.Show("Your Score : " + currentPoint + "\nAccuracy : " + Math.Round(accuracy).ToString("N0") + "%\nTotal Time : " + tmr/100 + "." + tmr%100 + " - seconds");
        }
    }

    private void StartGame()
    {
        lblAccuracy.Text = "0%";
        lblPoint.Text = "0/0";
        tmrStartCounter.Enabled = true;
        lblReady.Visible = true;
        startCounter = 6;
        bulletCount = 7;
        totalPoint = 0;
        currentPoint = 0;
        tmr = 0;
        lblTimer.Text = "0000";
        lblTotalBullet.Text = bulletCount.ToString();
        PlayingTime = true;
        picBullet1.Visible = true;
        picBullet2.Visible = true;
        picBullet3.Visible = true;
        picBullet4.Visible = true;
        picBullet5.Visible = true;
        picBullet6.Visible = true;
        picBullet7.Visible = true;
    }
}

December 8, 2009

Basic Window Application (Part 3)

Filed under: Window Form Application — Tags: , , , , — sevenlamp @ 10:23 AM

ေဘာလံုးေလး လႈိမ့္ရေအာင္

pic1

pic1

ဒီတစ္ေခါက္ ကြၽန္ေတာ္တို႔ ေဘာလံုးေလးကို form ေပၚမွာ လႈိမ့္ၾကရေအာင္။ အရင္ဆံုး picturebox တစ္ခုယူလိုက္ပါ။ ျပီးရင္ image property ကေန ေဘာလံုးပံုေလးကို import လုပ္ထားလိုက္ပါဦး။ picturebox ရဲ႕ property ေတြမွာ ေနာက္ထပ္ သိဖို႔ လိုတာ တစ္ခုက sizemode property ပါ။ sizemode property ကို ေလွ်ာက္ျပီး ေျပာင္းျပီး စမ္းၾကည့္လိုက္ရင္ သိသြားမွာပါ။ ကဲ အခု ေဘာလံုးပံုေလး ရသြားပါျပီ၊ ေရႊ႕ဖို႔ပဲ က်န္ေတာ့တယ္။ ကြၽန္ေတာ္က ပထမဆံုး အေနနဲ႔ေတာ့ keyboard က up – down, left – right keys ေလးေတြကို အသံုးျပဳျပီး ေဘာလံုးကို ေရႊ႕ခ်င္ပါတယ္။ ဒီေတာ့ keyboard က key ႏွိပ္ပါတယ္ဆိုတဲ႔ event မွာ ႏွိပ္လိုက္တဲ႔ key ကို ျပန္ျပီး စစ္ရပါမယ္။ picturebox မွာ key နဲ႔ ပါတ္သက္တဲ႔ event မရွိပါဘူး၊ ဒီေတာ့ ကြၽန္ေတာ္တို႔ form ရဲ႕ key events ေတြကိုပဲ သံုးရပါမယ္။ KeyDown, KeyUp နဲ႔ KeyPress event 3 ခုထဲကေနျပီး ကြၽန္ေတာ္တို႔ KeyDown or KeyUp event ကိုသံုးရပါမယ္။ ဘာလို႔လဲ ဆိုရင္ KeyPress Event မွာ Arrow keys ေတြကို ဖမ္းလို႔ အဆင္မေျပတာေၾကာင့္ပါ။

private void Form2_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Up)
    {
        if(pictureBox1.Top > 0)
            pictureBox1.Top -= 1;
    }
    else if (e.KeyCode == Keys.Down)
    {
        if(pictureBox1.Top+pictureBox1.Height < this.ClientSize.Height)
            pictureBox1.Top += 1;
    }
    else if (e.KeyCode == Keys.Left)
    {
        if(pictureBox1.Left > 0)
            pictureBox1.Left -= 1;
    }
    else if (e.KeyCode == Keys.Right)
    {
        if(pictureBox1.Left+pictureBox1.Width < this.ClientSize.Width)
            pictureBox1.Left += 1;
    }
}

keydown event မွာ user ရိုက္လိုက္တဲ႔ keycode ေလးကို ျပန္စစ္ရပါတယ္။ ျပီးေတာ့မွ up arrow ဆိုရင္ picturebox ေလးကို အေပၚကို ေရြ႕ဖို႔အတြက္ picturebox ရဲ႕ top property ကို ေလွ်ာ့ေပးလိုက္တာပါ။ ဒီအတိုင္းပဲ down arrow ဆိုရင္ေတာ့ top property ကို တိုးေပးရမွာပါ။ ဒီလို တိုးေပး ေလွ်ာ့ေပးလုပ္တဲ႔ ေနရာမွာ form ရဲ႕ အျပင္ဘက္ကို picturebox မေရာက္သြားရေလေအာင္ထိန္းထားေပးဖို႔လဲ လိုပါေသးတယ္။ ဒါ့ေၾကာင့္ ကြၽန္ေတာ္တို႔ up arrow ႏွိပ္တဲ႔ ေနရာမွာ picturebox ရဲ႕ top ကို form ရဲ႕ အေပၚဆံုးေနရာထက္ၾကီးလား စစ္ရပါတယ္။ အေပၚဆံုးေနရာက 0 ပါ။ ဒီလိုပါပဲ down arrow ႏွိပ္တဲ႔ ေနရာမွာလည္း pictureboxရဲ႕ ေအာက္ေျခက form ရဲ႕ ေအာက္ေျခထက္ ငယ္မွ ဆက္ျပီး ေရြ႕ခြင့္ေပးတာပါ။ ဒါဆိုရင္ left arrow နဲ႔ right arrow မွာ ေရးထားတာကိုလည္း နားလည္မွာပါ။ ေဘာလံုးေလးကို ပိုျပီး ျမန္ျမန္ေရြ႕ေစခ်င္ရင္ေတာ့ ၁ တိုး၊ ၁ေလွ်ာ့တဲ႔ ေနရာမွာ ၂ တို႔ ၃ တို႔ စသည္ျဖင့္ တိုးေပးလို႔ ရပါတယ္။

Automatic Moving the Ball

အခုကြၽန္ေတာ္က ဒုတိယ အဆင့္ေနနဲ႔ ေဘာလံုးေလး အခုလို ေရႊ႕တဲ႔ ကိစၥကို user key ႏွိပ္မွ မဟုတ္ပဲ၊ ဒီအတိုင္းထားရင္လည္း သူဟာသူ ေရြ႕ေနေစခ်င္ပါတယ္။ ဒါဆိုရင္ ဘယ္လို လုပ္ရမွာပါလဲ။ user ရဲ႕ action အတြက္ reaction မဟုတ္ပဲ program ကေန သူဟာသူ အလိုအေလွ်ာက္ အလုပ္လုပ္ေနေစခ်င္တဲ႔ ကိစၥတိုင္းအတြက္ ကြၽန္ေတာ္တို႔ Timer Control ကို သံုးရပါမယ္။ ကဲ… timer control ေလး form ထဲထည့္လိုက္ပါဦး။ Timer Control အေၾကာင္းကို ကြၽန္ေတာ္ Screen Server Program ေလးမွာ ေျပာျပီးပါျပီ။ timer control ရဲ႕ interval property မွာ ၁၀ ေလာက္ထား၊ enabled ကို true ေပးၿပီး၊ Tick event ထဲမွာ ေဘာလံုး ေရြ႕ဖို႔ လိုအပ္တဲ႔ code ေတြေရးေပးလိုက္ပါမယ္။

bool ToUp = true;
bool ToLeft = true;
private void timer1_Tick(object sender, EventArgs e)
{
    if (ToUp)
        pictureBox1.Top--;
    else
        pictureBox1.Top++;

    if (ToLeft)
        pictureBox1.Left--;
    else
        pictureBox1.Left++;

    if (pictureBox1.Top <= 0)         
        ToUp = false;     
    if (pictureBox1.Top + pictureBox1.Height >= this.ClientSize.Height)
        ToUp = true;

    if (pictureBox1.Left <= 0) 
        ToLeft = false;
    if (pictureBox1.Left + pictureBox1.Width >= this.ClientSize.Width)
        ToLeft = true;
}

ဒီေနရာမွာ နည္းနည္း ရွင္းဖို႔ လိုတာက အခုကြၽန္ေတာ္က ေဘာလံုးေလး ေရႊ႕တဲ႔ အလုပ္ေတြအားလံုး(အေပၚ၊ေအာက္… ) ကို event တစ္ခုထဲအတြင္းမွာ ေရးမွာ ျဖစ္တဲ႔ အတြက္၊ လက္ရွိ အေျခအေနက အေပၚဖက္ကို သြားေနတဲ႔ အခ်ိန္လား၊ ေအာက္ဆင္းေနတဲ႔ အခ်ိန္လား ဆိုတာကို မွတ္ထားဖို႔လိုပါတယ္။ ဒီလို မွတ္ထားဖို႔အတြက္ ToUp ဆိုတဲ႔ bool variable တစ္လံုးကို member variable အျဖစ္ေၾကာျငာထားလိုက္ပါတယ္။ အဲ့ဒီ ToUp ထဲမွာ true ဆိုရင္ အေပၚကို ေရႊ႕ဖို႔အတြက္ top ကို ၁ ေလွ်ာ့တယ္။ မဟုတ္ဘူး false ဆိုရင္ေတာ့ top ကို ၁ တိုးလိုက္ပါတယ္။ ျပီးေတာ့ ေဘာလံုးေလးက form ရဲ႕ အေပၚဆံုးကို ေရာက္ျပီဆိုရင္ ေအာက္ျပန္ဆင္းရမယ္ ဒါေၾကာင့္ အဲ့ဒီ ToUp ထဲကို false ထည့္ပါတယ္။ ဒီလိုပါပဲ ေအာက္ဆံုးေရာက္ျပီဆိုရင္လည္း အေပၚျပန္တက္ဖို႔အတြက္ ToUp ထဲကို true ျပန္ထည့္ေပးလိုက္ပါတယ္။ ဒါဆို ကြၽန္ေတာ့္ ေဘာလံုးေလးက အေပၚတက္လိုက္၊ ေအာက္ဆင္းလိုက္နဲ႔ အျမဲတမ္း ေရႊ႕ေနပါလိမ့္မယ္။ ဘယ္၊ညာ အတြက္လည္း ဒီသေဘာအတိုင္းပါပဲ။

ဒီ program ေလးမွာ ကြၽန္ေတာ္ အဓိက သိေစခ်င္တာက Key Event ေတြအေၾကာင္းနဲ႔ Timer Control အေၾကာင္းေလးပါ။ ေနာက္ျပီး Event တစ္ခုအတြင္းမွာ ဆန္႔က်င္ဖက္ အလုပ္ ၂ ခုကို ေရးရေတာ့မယ္ဆိုရင္ အခုလိုမ်ိဳး variable ေလးနဲ႔ ထိန္းျပီးသံုးရမယ္ဆိုလည္း သိရပါမယ္။ ေနာက္ဆံုးတစ္ခ်က္ကေတာ့ အခုလိုမ်ိဳးကိစၥေတြအတြက္ variable ေၾကာျငာမယ္ဆိုရင္ local variable ကိုသံုးလို႔ မရပါဘူး။ member variable ကိုေၾကာျငာမွသာလွ်င္ variable ထဲက တန္ဖိုးကို သိမ္းေပးထားနိုင္မွာပါ။

December 4, 2009

Basic Window Application (Part 2)

Filed under: Window Form Application — Tags: , , , , — sevenlamp @ 5:29 PM

Event 2 (Mouse Event)

ဒီေန႔ ကြၽန္ေတာ္တို႔ window form application ရဲ႕ event ေတြ အေၾကာင္းပဲ ဆက္ရေအာင္။ အခုကြၽန္ေတာ္က program run လိုက္ျပီး form ေပၚမွာ mouse ေရႊ႕ရင္ အဲ့ဒီ mouse pointer ရဲ႕ location ေလးကို form ရဲ႕ caption မွာ ျပခ်င္တယ္ဆိုပါေတာ့။ ဒါဆိုရင္ ကြၽန္ေတာ္က ဘယ္ event ကိုသံုးရမလဲ ဆိုရင္ Form ရဲ႕ Mouse Move Event ကိုသံုးရပါမယ္။

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
        this.Text = e.Location.ToString();
}

ကြၽန္ေတာ္က form Title bar မွာ မျပခ်င္ဘူး mouse pointer ေလးရဲ႕ ေဘးမွာ ပဲ location ေလးကို ေပၚေနေစခ်င္တယ္ဆိုရင္ေတာ့ Form ေပၚမွာ စာသားေတြ ျပဖို႔အတြက္ Label Control ကိုသံုးျပီး အခုလိုေရးရပါမယ္။

pic1

pic1

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
      label1.Left = e.X + 10;
      label1.Top = e.Y - 10;
      label1.Text = e.Location.ToString();
}

အရင္ဆံုး Form ေပၚမွာ Label တစ္ခုထည့္ရပါမယ္။ Mouse Move event မွာ အဲ့ဒီ Label ေလးရဲ႕ Location ကိုေရႊဖို႔အတြက္ Left နဲ႔ Top ကို mouse pointer လက္ရွိေရာက္ေနတဲ႔ location(x,y) သြားထည့္ေပးလိုက္ပါတယ္။ ဒီေနရာမွာ တစ္ခါတည္း သိလိုက္ဖို႔လိုတာက form ေပၚမွာ control ေတြ ေနရာေရႊ႕ခ်င္ရင္ အဲ့ဒီ control ရဲ႕ left နဲ႔ top ကို ေျပာင္းျခင္းအားျဖင့္ ေရႊ႕နိုင္တယ္ဆိုတာေလးပါ။

November 26, 2009

Shooting Game ေလးေရးရေအာင္

Shooting the best…. ( Exercise Two )

shooting the best...

pic_1

ကြၽန္ေတာ္တို႔ ေလ့က်င့္ခန္းေလး ေနာက္တစ္ခု အေနနဲ႔ ေသနတ္ပစ္တဲ႔ ဂိမ္းေလး ေရးၾကရေအာင္။ ဒီဂိမ္းေလးမွာ Timer Control ကို အဓိကသံုးထားပါတယ္။ ေနာက္တစ္ခုက Form ေပၚမွာ key ႏွိပ္တဲ႔ event မွာ user ႏွိပ္တဲ႔ key ကို ျပန္စစ္တဲ႔ အလုပ္ေလးလည္း ပါတာေပါ့။ ဒီ ၂ ခ်က္ထဲပဲ ေသခ်ာသိဖို႔လိုပါတယ္။ အိုေက… အားလံုးပဲ စမ္းေရးၾကည့္ၾကပါဦး။ ထံုးစံ အတိုင္း ေနာက္တစ္ပါတ္မွာ source code ကိုတင္ေပးပါ့မယ္။ ေလာေလာဆယ္ေတာ့ exe file ေလးကို ေဒါင္းျပီး runၾကည့္ play ၾကည့္ၾကပါဦး။

 

exe file

http://www.mediafire.com/download.php?gnzww3iyjnc

November 6, 2009

Basic Window Application (Part 1)

Filed under: Window Form Application — Tags: , , , , — sevenlamp @ 5:03 PM

Event

Window Form Application ေတြမွာ အေရးၾကီးတဲ႔ အစိတ္အပိုင္း တစ္ခုအေနနဲ႔ သိဖို႔လာလိုလာတာက Event ဆိုတာေလးပါ။ ဟုတ္ျပီ… Event ဆိုတာဘာလဲ? Event ဆိုတာကို အလြယ္ေျပာရရင္ အျဖစ္အပ်က္တစ္ခုလို႔ ေျပာရပါမယ္။ အျပင္ေလာကမွာ မိုးရြာတယ္၊ မိုးခ်ိန္းတယ္၊ ေလတိုက္တယ္၊ အုန္းသီးေၾကြတယ္ :D စသည္ျဖင့္ေပၚ အဲ့ဒီလို ျဖစ္သြားတာေတြ အားလံုးကို Event လို႔ ေျပာလို႔ ရမယ္ထင္ပါတယ္။ ကြၽန္ေတာ္တို႔ Programming မွာ လည္း user ရဲ႕ လုပ္ေဆာင္မႈေပၚမူတည္ျပီး ျဖစ္ပ်က္သြားတာေတြ အားလံုးကို Event လို႔ေခၚပါတယ္။ User က Window Form ေပၚမွာ Mouse ကို ႏွိပ္လိုက္ရင္ ႏွိပ္တယ္ ဆိုတဲ႔ အျဖစ္အပ်က္ျဖစ္ပါတယ္။ ဒီလိုပါပဲ Form ၾကီးကို ပိတ္လိုက္ရင္လည္း Form ပိတ္တယ္ဆိုတဲ႔ အျဖစ္အပ်က္ျဖစ္သြားပါတယ္။ အဲ့ဒီလိုမ်ိဳး User ရဲ႕ action တိုင္း အတြက္ Event ေတြျဖစ္ေနပါတယ္။ အဲ့ဒီလို Event ေတြ ျဖစ္သြားတဲ႔ အခ်ိန္မွာ ကြၽန္ေတာ္တို႔ programmer ေတြက user ေတြကို ျပန္ျပီး ေပးခ်င္တဲ႔ response ေတြ ရွိလာျပီဆိုရင္ေတာ့ အဲ့ဒီ အတြက္ Coding ေတြ ေရးေပးရပါမယ္။ ( ဥပမာ user က form ကို click လုပ္ရင္ Hello လို႔ user ကို ျပခ်င္တယ္။ ဒါမွမဟုတ္ form ေပၚမွာ mouse ေရႊ႕ရင္ mouse pointer ရဲ႕ location ေလး ျပခ်င္တယ္။ စသည္ျဖင့္ေပါ..)။ အဲ့ဒီလို ေရးဖို႔ လုပ္တာကို Event Handling လုပ္တယ္လို႔ ေခၚပါတယ္။ Event ကို Handle လုပ္တာကလည္း အေရးၾကီးပါတယ္။ ကြၽန္ေတာ္တို႔ ကုဒ္ေတြ မေရးခင္ အရင္ဆံုး ဘယ္ event မွာ ေရးရမွာလဲ ဆိုတာကို ခြဲျခားေရြးနိုင္ဖို႔ လိုပါတယ္။ ကြၽန္ေတာ္က Mouse_Click Event မွာ ေရးရမယ္ ကုဒ္ကို Key_Press Event မွာ သြားေရးရင္ Mouse ႏွိပ္တဲ႔အခါ အလုပ္လုပ္မွာ မဟုတ္ပါဘူး။

အခုကြၽန္ေတာ္တို႔ window form ရဲ႕ event ေလးေတြကို နည္းနည္း ေလ့လာလိုက္ရေအာင္။ Form မွာ ပထမဆံုး သိဖို႔လိုတဲ႔ event က Load Event ပါ။ ကြၽန္ေတာ္တို႔ Form object ကို memory ေပၚဆြဲတင္တဲ႔ အခ်ိန္မွာ form load event ျဖစ္ပါတယ္။ form load event က form ၾကီး screen မွာ မေပၚခင္ျဖစ္တာ ျဖစ္တဲ႔အတြက္ေၾကာင္း form မွာ initialize လုပ္ဖို႔ လိုတဲ႔ အပိုင္းေတြကို form load ထဲမွာ ေရးေပးေလ့ရွိတယ္။ ဥပမာ.. ကြၽန္ေတာ္က form ေပၚလာတာနဲ႔ form background color ကို random color ေလး ျဖစ္ေစခ်င္တယ္ဆိုရင္ form load event ထဲမွာ ဒီလိုေလး ေရးေပးရမွာပါ….

private void Form1_Load(object sender, EventArgs e)
{      
        Random rnd = new Random();      
        this.BackColor = Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256));
}

ဒီလိုပါပဲ.. form ၾကီး ေပၚေနတဲ႔ အခ်ိန္မွာ form ေပၚမွာ click ႏွိပ္တိုင္းမွာလည္း ကာလာေျပာင္းေနခ်င္တယ္ ဆိုရင္ Form ရဲ႕ Click Event မွာပါ သြားေရးေပးရမွာပါ။

private void Form1_Click(object sender, EventArgs e)
{
        Random rnd = new Random();      
        this.BackColor = Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256));
}

အခုကြၽန္ေတာ္က form ကို user က ပိတ္လိုက္တဲ႔ အခ်ိန္မွာ user ကို ပိတ္မွာ ေသခ်ာလားဆိုျပီး confirm message ေလး ေမးခ်င္တယ္ဆိုပါေတာ့… ဒါဆိုရင္ ဘယ္မွာ ေရးရမွာလဲ ? ဟုတ္ကဲ႔ Form ရဲ႕ FormClosing Event မွာ ေရးရပါမယ္။ ဒီလိုမ်ိဳးပါ…

Pic_1

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{     
       DialogResult res = MessageBox.Show("Sure to close?", "Confirm...",
                         MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
       if (res == DialogResult.No)
               e.Cancel = true;
}

MessageBox class ထဲက show function ေလးကို ေခၚလိုက္ရင္ ကြၽန္ေတာ္တို႔ form ေပၚမွာ dialog form ေလး တစ္ခု ျပေပးပါတယ္။ dialog form ဆိုတာက အဲ့ဒီ form ေပၚေနရင္ တျခား form ေတြကို အလုပ္ဆက္လုပ္လို႔ မရပါဘူး။ အဲ့ဒီ dialog form ပိတ္သြားမွ အလုပ္ဆက္လုပ္လို႔ ရပါတယ္။ အဲ့ဒီ MessageBox form ေလးရဲ႕ Show function မွာ အဓိက parameter ၄ ခု ေပးလို႔ ရပါတယ္။

၁ – ေပၚခ်င္တဲ႔ Message ( here : Sure to close? )
၂ – Title bar Text ( here : Confirm… )
၃ – ေပၚခ်င္တဲ႔ Button အမ်ိဳးအစားေတြ ( here : Yes and No )
MessageBoxButtons ဆိုတဲ႔ enum ေလးထဲက တန္ဖိုး တစ္ခုခုေရြးေပးရပါမယ္။ default ကေတာ့ OK button ပါ။
၄ – ေပၚခ်င္တဲ႔ Icon ( here : Warning )
ဒါလည္း တူတူပါပဲ… MessageBoxIcon အမ်ိဳးအစား enum ပါ။

ဒီ parameter ၄ ခုကို နံပါတ္ ၁ တစ္ခုထဲ ေပးမယ္ဆိုလည္း ရပါတယ္။ ဒါေပမယ့္ နံပါတ္ ၂ ပဲေပးမယ္ဆိုရင္ေတာ့ မရပါဘူး။ နံပါတ္ ၃ ကိုေပးခ်င္တယ္ဆိုရင္ နံပါတ္ ၁ ေရာ နံပါတ္ ၂ ပါေပးမွ ရပါမယ္။

Dialog form ေတြအားလံုး ပိတ္သြားတဲ႔ အခ်ိန္မွာ DialogResult အမ်ိဳးအစား enum တစ္ခု return ျပန္ပါတယ္။ အခု ျပန္လာတဲ႔ return value ကို ကြၽန္ေတာ္က No နဲ႔ ညီလား ဆိုျပီး စစ္လိုက္ပါတယ္။ (ကြၽန္ေတာ္က MessageBoxButtons မွာ YesNo ကိုေရြးလိုက္တဲ႔အတြက္ Return value ဟာ Yes ေသာ္လည္းေကာင္း၊ No ေသာ္လည္းေကာင္း return ျပန္ပါ့မယ္။ ) ကြၽန္ေတာ္တို႔ အခုေရးေနတဲ႔ Event က form ပိတ္တဲ႔ event ျဖစ္တဲ႔အတြက္ User က Yes ကိုႏွိပ္ရင္ ကြၽန္ေတာ္တို႔က ဘာမွ လုပ္ေပးစရာ မလိုပါဘူး။ အဲ.. User က No ကိုႏွိပ္ရင္ေတာ့ ကြၽန္ေတာ္တို႔က Form မပိတ္ေအာင္ e.Cancel ထဲကို true value သြားထည့္ေပးရပါတယ္။ ဒါဆို form မပိတ္ေတာ့ပါဘူး။ ခုေလာက္ဆို Event ဆိုတာကို နည္းနည္း နားလည္လာမယ္ ထင္ပါတယ္။

November 5, 2009

Exercise One Video

ကြၽန္ေတာ္ exercise အေနနဲ႔ ေပးခဲ႔တဲ႔ Screen Saver Program ေလးကို မေန႔ညက ကြၽန္ေတာ္ Video Training ေလး လုပ္လာခဲ႔တယ္။ ေသေသခ်ာခ်ာေလးေတာ့ လုပ္ေပးထားပါတယ္။ ညီတို႔ ေဒါင္းျပီး ၾကည့္ၾကည့္ပါဦး။ မရွင္းတာရွိရင္ ျပန္ေမးေစခ်င္ပါတယ္။ ကြၽန္ေတာ္ Video Training လုပ္ဖို႔ သံုးတဲ႔ software က SnapIt9 ပါ။ အဲ့ဒီ software ရဲ႕႔ အားနည္းခ်က္ေၾကာင့္ထင္တယ္ ေျပာေနရင္း အခ်ိန္ၾကာလာရင္ အသံက ျမန္ျပီး ရုပ္ပံုက ေႏွးေနတာေလး တစ္ခုေတာ့ ရွိတယ္။ အဲ့ဒါေလး သည္းခံျပီး နားေထာင္ေပးၾကပါခင္ဗ်ာ။ အဲ… ေနာက္တစ္ခုက ကြၽန္ေတာ္ရဲ႕ အသံဆိုးဆိုးေလးကိုလည္း သည္းခံေပးပါေနာ္ :)

ကြၽန္ေတာ္ အပိုင္း ၅ ပိုင္း ခြဲျပီး တင္ပါမယ္။ ၁ပိုင္းစီကို rar file ေျဖျပီး နားေထာင္လို႔ရတယ္ေနာ္။ အားလံုး ေဒါင္းျပီးမွ ၾကည့္စရာမလိုဘူး။ Source Code ကိုလည္း ထည့္ေပးလိုက္ပါတယ္။ အဲ့ဒါေလးကို ၾကည့္ျပီး ကိုယ္တိုင္ ျပန္လုပ္ၾကည့္ပါ။ ရသြားရင္… ဒါမ်ိဳး ဆင္တူေလးေတြကို ကိုယ္တိုင္စမ္းလုပ္ၾကည့္ပါ။ (ဥပမာ.. အခုကြၽန္ေတာ္က line ဆြဲျပထားတယ္ အဲ့ဒီအစား စက္၀ိုင္းတို႔ ဘာတို႔ လုပ္ၾကည့္ေပါ့ေနာ္ )

ညီ၊ညီမ တို႔ အားလံုး programming ကို အခက္အခဲမရွိ ေလ့လာနိုင္ၾကပါေစ….

Part One :
http://www.sendspace.com/file/5yrx3u

 

Part Two :
http://www.sendspace.com/file/t3wji1

 

Part Three :
http://www.sendspace.com/file/6gbway

 

Part Four :
http://www.sendspace.com/file/r58ep8

 

Part Five :
http://www.sendspace.com/file/cxwb2y

 

Source Code :
http://www.sendspace.com/file/we1wb9

October 31, 2009

Graphics And Random

Filed under: Window Form Application — Tags: , , , , — sevenlamp @ 2:32 PM

Graphics Class

ကြၽန္ေတာ္တို႔ ပံုေတြဆြဲခ်င္ျပီဆိုရင္ ဘာေတြလိုအပ္မလဲ။ အရင္ဆံုး ဆြဲဖို႔အတြက္ ေနာက္ခံတစ္ခုလိုပါမယ္။ စာရြက္ေသာ္လည္းေကာင္း၊ နံရံေသာ္လည္းေကာင္း၊ ပိတ္ကား ေသာ္လည္းေကာင္းေပါ့။ ေနာက္ျပီး ဆြဲမယ့္ ခဲတံျဖစ္ျဖစ္ စုတ္တံျဖစ္ျဖစ္လိုပါမယ္။ ဒီ ၂ ခုရွိျပီဆိုရင္ေတာ့ ကြၽန္ေတာ္တို႔ ပံုေတြ ဆြဲလို႔ရပါၿပီ။ ဒီအတုိင္းပါပဲ ကြၽန္ေတာ္တို႔ C# window application မွာ graphic ပံုေတြ ဆြဲဖို႔ လိုအပ္လာျပီဆိုရင္လည္း ဆြဲခ်င္တဲ႔ ေနာက္ခံ object နဲ႔ ဆြဲမယ့္ pen or brush လိုအပ္ပါတယ္။ တကယ္ဆြဲတဲ႔ အလုပ္ကိုေတာ့ graphics object ကေနတဆင့္လုပ္ေပးရပါမယ္။ အရင္ဆံုး Graphics Class ကို object ေဆာက္ရပါမယ့္။ ဒီလို ေဆာက္တဲ႔အခါ ကြၽန္ေတာ္တို႔ ဆြဲခ်င္တဲ႔ ေနာက္ခံobject ကေနတဆင့္ CreateGraphic() ဆိုတဲ႔ function ကိုသံုးၿပီးေဆာက္ရမွာပါ။ ဒီလိုမ်ိဳးပါ..

Graphics g = this.CreateGraphics();          // form ေပၚမွာ ဆြဲရန္…

Graphics g = label1.CreateGraphics();       // label ေပၚမွာ ဆြဲရန္…

ေနာက္ခံကိုေရြးၿပီးၿပီဆိုရင္ အခုလိုအပ္တာက ဆြဲမယ့္ ခဲတံပါ။ ကြၽန္ေတာ္ဆြဲမယ့္ပံုမွာ outline အနားသပ္ပဲ ပါမယ္ဆိုရင္ Pen class ကိုသံုးရၿပီး။ အတြင္းသား ကိုပါ အေရာင္ျဖည့္မယ္ဆိုရင္ေတာ့ Brush class ကိုသံုးရပါမယ္။ ကြၽန္ေတာ္လိုခ်င္တဲ႔ အေရာင္ကိုလည္း တခါတည္း ေျပာေပးလိုက္ပါမယ္။

Pen p = new Pen (Color.Red);                 // အနီေရာင္ ခဲတံေလး တစ္ခုယူလိုက္တာပါ။

လိုင္းရဲ႕ အထူအပါးကိုပါ ခ်ိန္ေပးလို႔လည္း ရပါတယ္။ pen class မွာ width property မွာ ျပင္ေပးလို႔ရပါတယ္။

p.Width = 2;            // line အထူ 2 pixel ယူပါမယ္။

ဒါမွမဟုတ္… Pen object ေဆာက္တုန္းမွာပဲ constructor ထဲမွာတခါတည္း ထည့္ေပးလိုက္လည္း ရပါတယ္။

Pen p = new Pen (Color.Red, 2);

Brush object ေဆာက္ရင္ေတာ့ တစ္ခ်က္သတိထားရမွာက Brush class ကိုယ္တိုင္ကို object ေဆာက္လို႔ မရပါဘူး။ သူ႔ရဲ႕ child class (SolidBrush, LinearGradientBrush,…) ေတြကိုပဲ object ေဆာက္လို႔ရပါတယ္။

Brush b = new SolidBrush (Color.Green);   // အစိမ္းေရာင္ စုတ္တံေလးတစ္ခုယူလိုက္တာပါ။

ကဲ.. အခုေနာက္ဆံုး ကြၽန္ေတာ္တို႔ တကယ္ဆြဲပါေတာ့မယ္။ Pen ကိုသံုးမယ္ဆိုရင္ Draw function ေတြကိုသံုးရျပီး၊ Brush ကိုသံုးမယ္ဆိုရင္ေတာ့ Fill Function ကို သံုးရပါတယ္။ အခုကြၽန္ေတာ္ width 100, height 100 ရွိတဲ႔ အစိမ္းေရာက္ box ေလးကို အနီေရာင္အနားကြပ္ေလးနဲ႔ လိုခ်င္တယ္ဆိုရင္…..

Graphics g = this.CreateGraphics();

Pen p = new Pen(Color.Red, 2);

Brush b = new SolidBrush(Color.Green);

g.FillRectangle(b, 10, 10, 100, 100);

g.DrawRectangle(p, 10, 10, 100, 100);

ေနာက္သိဖို႔ တစ္ခုလိုေသးတာက ဒီကုဒ္ေတြေရးရမယ့္ event ပါ။ Form စေပၚလာလာခ်င္းမွာ ေပၚခ်င္ရင္ Form_Paint event မွာ ေရးရပါမယ္။ Button တစ္ခုခုကိုႏွိပ္မွ ဆြဲမယ္ဆိုရင္ေတာ့ အဲ့ဒီ button_click event မွာ ေရးရမွာေပါ့။ Paint event မွာ မေရးထားတာေတြ အားလံုးက form ကို Minimax လုပ္လိုက္ရင္ အကုန္ ေပ်ာက္သြားမွာပါ။

Random Class

ကြၽန္ေတာ္တို႔ C# programming language မွာ random ေခါက္ခ်င္ၿပီဆိုရင္ Random Class ကိုသံုးရပါတယ္။ Random ေခါက္တယ္ဆိုတာက သက္မွတ္ထားတဲ႔ range တစ္ခုအတြင္းမွာ ျဖစ္ခ်င္တာျဖစ္ဆိုျပီး တစ္ခုကို ေရြးလိုက္တာပါ။

Random rnd = new Random();

rnd.Next();              // Integer value တစ္ခု return ျပန္ပါတယ္။

rnd.Next(10);           // 0 – 9 ထဲက value တစ္ခု return ျပန္ပါတယ္။

rnd.Next(2, 6);         // 2 – 5 ထဲက value တစ္ခု return ျပန္ပါတယ္။

ကဲ ဟုတ္ၿပီ အခုကြၽန္ေတာ္က ခုန rectangle ေလးရဲ႕ location ေလးကိုကို form ေပၚမွာ random ေပၚေအာင္ ေရးၾကည့္ရေအာင္။

Random rnd = new Random();

int x = rnd.Next(this.ClientSize.Width);

int y = rnd.Next(this.ClientSize.Height);

Graphics g = this.CreateGraphics();

Pen p = new Pen(Color.Red, 2);

Brush b = new SolidBrush(Color.Green);

g.FillRectangle(b, x, y, 100, 100);

g.DrawRectangle(p, x, y, 100, 100);

October 29, 2009

screensaver အတုေလး ေရးရေအာင္

ကြၽန္ေတာ္တစ္ခု စဥ္းစားမိတာ ရွိတယ္။ ကြၽန္ေတာ္တို႔ အတူတူ C# program ေလးေတြ ေရးၾကရေအာင္။ အရင္ဆံုး ကြၽန္ေတာ္က ေရးျပီးသား exe file ေလး တင္ေပးမယ္။ ညီတို႔က အဲ့ဒီ exe file ေလးကို run ၾကည့္ျပီး။ အဲ့ဒီ result အတိုင္းထြက္ေအာင္ ၾကိဳးစားျပီး program ေရးၾကည့္ၾကပါ။ တစ္ပါတ္ၾကာရင္ ကြၽန္ေတာ္က အဲ့ဒီ program ကို ျပန္ရွင္းျပျပီး source code တင္ေပးပါ့မယ္။ ၾကားထဲမွာ ညီတို႔ ေရးတဲ႔ program ကို ကြၽန္ေတာ္ email ကို ပို႔ေပးရင္လည္း ကြၽန္ေတာ္ စစ္ေပးပါမယ့္။ ဒီလို လုပ္ျခင္း အားျဖင့္ ကိုယ္တိုင္ ေလ့လာတဲ႔ အေလ့အက်င့္ေလးလည္း ရသြားမယ္။ program လည္း ေရး က်င့္ရသြားမယ္ေပါ့။
ကဲ အရင္ဆံုး C# window application နဲ႔ ေရးထားတဲ႔ Screen server ပံုစံ program ေလး နဲ႔ စေရးလိုက္ရေအာင္။
exe file ေလးကို ဒီကေန ယူျပီး run ၾကည့္ပါ။

http://www.sendspace.com/file/xy2ql1

note:

ဒီ program ေလးေရးဖို႔အတြက္

1 – Graphics class အေၾကာင္း

2 – Random class အေၾကာင္း

3 – Array အေၾကာင္း

4 – Timer Control အေၾကာင္းကို သိဖို႔လိုပါတယ္။

တကယ္ လိုက္ျပီး ေရးၾကလိမ့္မယ္လို႔ ေမွ်ာ္လင့္ပါတယ္….

October 2, 2009

basic of C# (part 25)

Filed under: Basic of C# — Tags: , , , , , — sevenlamp @ 10:21 AM

Function Overloading Vs Function Overriding

ကြၽန္ေတာ္တို႔ ဒီေန႔ function overloading နဲ႔ function overriding အေၾကာင္းေလး ေျပာၾကရေအာင္။ အရင္ဆံုး function overloading အေၾကာင္းေျပာရေအာင္။ overload ဆိုတာ အလုပ္တစ္ခုထက္ပိုျပီး လုပ္တာကို ေျပာခ်င္တာပါ။ function overloading ဆိုေတာ့ ကြၽန္ေတာ္တို႔ ေရးလိုက္တဲ႔ function က တာ၀န္ တစ္ခုထက္ပိုျပီး လုပ္ေဆာင္ေပးတာကိုရည္ရြယ္တာပါ။ function name က တစ္ခုထဲပဲ ဒါေပမယ့္ လုပ္ေဆာင္မႈအမ်ားၾကီး လုပ္နိုင္ေအာင္ေပါ့။ ဥပမာဗ်ာ.. ကြၽန္ေတာ္က string ကေန integer ေျပာင္းတဲ႔ function ေလးတစ္ခုေလာက္ ေရးခ်င္တယ္။

static int ConvertToInteger(string st)
{
    try
    {
        return Convert.ToInt32(st);
    }
    catch
    {
        return 0;
    }
}

ကဲ.. ဒီ function ေလး ေရးလိုက္ျခင္းအားျဖင့္ ကြၽန္ေတာ္တို႔ string ကေန integer ေျပာင္းခ်င္တိုင္း လြယ္လြယ္ကူကူ ေခၚလို႔ ရသြားမယ္။ ဒါေပမယ့္ တျခား type ေတြကေနေျပာင္းခ်င္ရင္ ဒီ function သံုးလို႔ ရမလား။ မရပါဘူး။ ဒါဆို ကြၽန္ေတာ္က တျခားtype ေတြ အတြက္ကိုလည္း ဒီလိုမ်ိဳး function ေတြ ထပ္ေရးေပးဖို႔ လိုပါလိမ့္မယ္။

static int ConvertToInteger(decimal dec)
{
    try
    {
        return Convert.ToInt32(dec);
    }
    catch
    {
        return 0;
    }
}
static int ConvertToInteger(long l)
{
    try
    {
        return Convert.ToInt32(l);
    }
    catch
    {
        return 0;
    }
}

ဟုတ္ျပီေနာ္.. အခုလိုမ်ိဳး function name တူျပီး parameter မတူတဲ႔ function ေတြ တစ္ခုထက္ပိုျပီး ေရးလိုက္တာကို function overloading လုပ္တယ္လို႔ ေခၚပါတယ္။ function overloading လုပ္ျခင္း အားျဖင့္ ဘာပိုေကာင္းလာမလဲ။ ဟုတ္ကဲ႔ ကြၽန္ေတာ္တို႔ program ေရးတဲ႔ေနရာမွာ အမ်ားၾကီးပိုျပီး လြယ္ကူေစပါတယ္။ အကယ္လို႔သာ function overload မလုပ္ရဘူးဆိုရင္ ကြၽန္ေတာ္တို႔ string ကေန integer ေျပာင္းဖို႔အတြက္က function name တစ္ခု၊ decimal ကေန integer ေျပာင္းဖို႔အတြက္က function name တစ္ခု၊ long ကေန integer ေျပာင္းဖို႔အတြက္က function name တစ္ခု စသည္ျဖင့္ name ေတြ အမ်ားၾကီး သံုးေနမွတ္ေနရမွာေပါ့။ အခု overloading လုပ္ျခင္းအားျဖင့္ function name တစ္ခုထဲကိုပဲ သိဖို႔ လိုပါေတာ့တယ္။ Framework class library ထဲမွာလည္း overload လုပ္ထားတဲ႔ function ေတြ အမ်ားၾကီး ေတြရမွာပါ။ ကဲ အႏွစ္ခ်ဳပ္ျပန္ေျပာပါမယ္ function overloading ျဖစ္ဖို႔အတြက္ function name တူရပါမယ္၊ argument (parameter) မတူရပါဘူး။ parameter မတူရဘူး ဆိုတာမွာ parameter ရဲ႕ datatype ျဖစ္ေစ၊ အရည္အတြက္ ျဖစ္ေစမတူရင္ ရပါတယ္။

ေနာက္တစ္ခုကေတာ့ function overriding။ overriding လို႔ ေျပာတဲ႔ အတိုင္းပါပဲ၊ function overrideing ဆိုတာက function တစ္ခုေပၚမွာ ေနာက္ထပ္ function တစ္ခုနဲ႔ ထပ္ျပီး အုပ္လိုက္တာကို ေျပာခ်င္တာပါ။ ဒီလိုလုပ္လိုက္ရင္ function ၂ ခု ျဖစ္သြားမလား၊ မျဖစ္ပါဘူး။ override လုပ္ျခင္းခံရတဲ႔ function က ေပ်ာက္သြားမွာပါ။ function overrideing ကို အဓိကအားျဖင့္ polymorphism နဲ႔ တြဲျပီးသံုးေလ့ ရွိပါတယ္။ parent class ထဲမွာ ရွိျပီးသား function တစ္ခုကို child class ထဲမွာျပန္ျပီးေရးခ်င္တယ္ ဆိုရင္ override လုပ္ဖို႔ လိုလာပါျပီ။ ဒီလို အခ်ိန္မ်ိဳးမွာ function overriding ကိုသံုးပါတယ္။ ဥပမာေလးနဲ႔ ေျပာရရင္… ကြၽန္ေတာ္မွာ animal ဆိုတဲ႔ class ရွိတယ္ဗ်ာ၊ parent class ေပါ့၊ အဲ့ဒီ animal class ထဲမွာ eat() ဆိုတဲ႔ function ေလးပါတယ္။

class animal
{
    public void eat()
    {
        Console.WriteLine("Eat something");
    }
}

အိုေက.. အဲ့ဒီ animal class မွာ child class ၂ ခုရွိတယ္။ dog class နဲ႔ ant class ေပါ့။ အဲ့ဒီ dog class နဲ႔ ant class က animal class ကေန inheritance လုပ္ထားတာျဖစ္တဲ႔ အတြက္ သူတို႔ဆီမွာ eat() function အလိုအေလွ်ာက္ ပါလာပါတယ္။ အဲ့ဒီ parent class ကေနပါလာတဲ႔ eat() function ထဲက statement ေတြကို child class မွာ မလိုခ်င္ဘူး။ ပိုျပီး detail ၾကတဲ႔ message နဲ႔ အစားထိုးခ်င္တယ္ဆိုပါေတာ့ (ဥပမာ.. Eat something အစား၊ Eat Bone တို႔ Eat sugur တို႔နဲ႔ အစားထိုးခ်င္ျပီဆိုရင္)၊ ဒါဆို ဘယ္လိုလုပ္မလဲ? ေနာက္ထပ္ function တစ္ခုထပ္ေဆာက္ခ်င္တာ မဟုတ္ဘူးေနာ္၊ parameter လည္း မေျပာင္းတဲ႔ အတြက္ overloading လည္း လုပ္လို႔ မရဘူး။ ဒီလို အေျခအေနမ်ိဳးမွာ ကြၽန္ေတာ္တို႔ မျဖစ္မေန function overriding လုပ္ဖို႔ လိုလာပါျပီ။

ဒါဆို function overriding လုပ္ဖို႔ ဘာလိုမလဲ? Parent class ထဲမွာ ဒီတိုင္းေရးထားတဲ႔ function တိုင္းကိုေတာ့ override လုပ္လို႔ မရပါဘူး။ override လုပ္ဖို႔ ခြင့္ျပဳထားတဲ႔ function ေတြကိုပဲ လုပ္လို႔ရတာပါ။ ဒီလို override လုပ္ဖို႔ ခြင့္ျပဳခ်င္တယ္ဆိုရင္ parent class ထဲက function ရဲ႕ေရွ႕မွာ virtual ဆိုတဲ႔ keyword ေလးထည့္ေရးေပးလိုက္ရပါတယ္။

class animal
{
    public virtual void eat()
    {
        Console.WriteLine("Eat something");
    }
}

override ျပန္လုပ္မယ့္ child class က function ေရွ႕မွာေတာ့ override ဆိုတဲ႔ keywordကို ထည့္ေပးရပါတယ္။

class dog : animal
{
    public override void eat()
    {
        Console.WriteLine("Eat Bone!");
    }
}

ကဲ… example program ေလး တစ္ခုေလာက္ေရးၾကည့္ပါဦး။

class animal
{
    public virtual void eat()
    {
        Console.WriteLine("Animal: Eat something");
    }
}
class dog : animal
{
    public override void eat() // function overriding
    {
        Console.WriteLine("Dog: Eat Bone!");
    }
}
class ant : animal
{
    public override void eat()
    {
        Console.WriteLine("Ant: Eat Sugar");
    }
}
class Program
{
    static void Main()
    {
        animal obj;
        obj = new animal();
        obj.eat();

        obj = new dog(); //polymorphism
        obj.eat();

        obj = new ant();
        obj.eat();

        Console.Read();
    }
}

Basic of C# ကို ကြၽန္ေတာ္ဒီမွာပဲ ရပ္လိုက္ပါေတာ့မယ္။ အခုေလာက္ဆိုရင္ ကြၽန္ေတာ္တို႔ C# ဆိုတာ ဘာလဲသိေလာက္ပါျပီ။ OOP အေၾကာင္းလည္း နည္းနည္းေတာ့ နားလည္ေလာက္ျပီလို႔ ယူဆပါတယ္။ ေနာက္ပိုဒ႔္ေတြမွာ window application အပိုင္းနဲ႔ web application အပိုင္းကို ဆက္ေရးသြားပါ့မယ္ခင္ဗ်ာ။

September 29, 2009

basic of C# (part 24)

Filed under: Basic of C# — Tags: , , , , , , , — sevenlamp @ 9:55 AM

ကဲ ဒီေန႔ေတာ့ database အပိုင္းေလး ခဏနားျပီး C# ဘက္ကို နည္းနည္းျပန္လွည့္ေအာင္။ ကြၽန္ေတာ္တို႔ အခုေနာက္ပိုင္း programming language မွာ အသံက်ယ္က်ယ္ေလာင္ေလာင္ ျဖစ္လာတာက OOT လို႔ ေခၚတဲ႔ Object-Oriented Technique ပဲျဖစ္ပါတယ္။ OO မွာ ဘာေတြပါလဲ…

အေမြဆက္ခံျခင္းလို႔ ေခၚတဲ႔ inheritance၊

အသြင္ေျပာင္းျခင္းလို႔ေျပာလို႔ရတဲ႔ Polymorphism၊

Data hiding လို႔ေခၚတဲ႔ member data ေတြကို သို၀ွက္သိမ္းဆည္းထားျခင္း၊

Encapsulation သိမ္းဆည္းထားတဲ႔ member data ေတြကို တဆင့္ခံျဖင့္ သံုးခြင့္ေပးျခင္း၊

စသည္ျဖင့္ေပါ႔ဗ်ာ.. အဲ့ဒါေတြ ပါပါတယ္။

Inheritance အေမြဆက္ခံျခင္းဆိုတာဘာလဲ???

ဒီလိုေလးေတြးၾကည့္ရေအာင္ဗ်ာ အခုကြၽန္ေတာ္တို႔ မိဘေတြပိုင္ဆိုင္တဲ႔ ပိုင္ဆိုင္မႈေတြဟာ ကြၽန္ေတာ္တို႔ရဲ႕ ပိုင္ဆိုင္မႈေတြပါပဲ။ ဒီလိုပါပဲ ကြၽန္ေတာ္တို႔ရဲ႕ ပိုင္ဆိုင္မႈေတြကိုလည္း ကြၽန္ေတာ္တို႔ရဲ႕ မ်ိဳးဆက္သစ္ေတြက ပိုင္ဆိုင္ၾကဦးမွပါ။ ဒီသေဘာတရားေလးကို ယူျပီး OOမွာ inheritance ဆိုတာေပၚေပါက္လာတာပါ။ class တစ္ခုရဲ႕ ပိုင္ဆိုင္မႈ property ေတြဟာ အဲ့ဒီ class ရဲ႕ child ေတြကလည္း ပိုင္ဆိုင္နိုင္ပါတယ္။ ဒီလို ပိုင္ဆိုင္နိုင္ျခင္းအားျဖင့္ ကြၽန္ေတာ္တို႔က class ေတြအားလံုး အတြက္ တူညီတဲ႔ property ေတြကို အၾကိမ္ၾကိမ္ေၾကျငာေပးေနစရာ မလိုေတာ့ပါဘူး။ ဥပမာဗ်ာ ကြၽန္ေတာ္က လူတစ္ေယာက္ကို ကိုယ္စားျပဳမယ့္ class တစ္ခုေဆာက္မယ္ဆိုရင္ အဲ့ဒီ class ထဲမွာ ဘယ္လို member ေတြပါမလဲ စဥ္းစားၾကည့္၊ နံမည္ပါမယ္၊ အသက္ပါမယ္၊ ေနရပ္လိပ္စာပါမယ္ဗ်ာ၊ စသည္ျဖင့္ေပါ့။

class People
{
    string Name;
    int Age;
    string Address;
}

ကဲ…အခု ေနာက္တစ္ခါ ကြၽန္ေတာ္က ေက်ာင္းသားတစ္ေယာက္ကို ကိုယ္စားျပဳမယ့္ class တစ္ခုထပ္ေဆာက္ဖို႔ လိုလာျပီဆိုရင္ေရာ ဘယ္လို member ေတြပါမလဲ၊ ေက်ာင္းသားမွာလည္း နံမယ္ပါမယ္၊ အသက္ပါမယ္၊ လိပ္စာပါမွာပါပဲ၊ ေက်ာင္းသားမွာ ပိုပါလာတာက roll နံပါတ္ပါမယ္၊ class ပါပါမယ္။

class Student
{
    string Name;
    int Age;
    string Address;
    int Roll;
    int Class;
}

ဟုတ္ျပီ ဒီလိုအေျခအေနမ်ိဳးမွာ နံမည္တို႔ အသက္တို႔ကို ထပ္ျပီး မေၾကျငာခ်င္ဘူးဆိုရင္ ကြၽန္ေတာ္တို႔ Student class ကို People class ရဲ႕ child အျဖစ္ ေၾကျငာလို႔ ရပါတယ္။ ဒီလိုမ်ိဳးပါ…

class Student : People
{
    int Roll;
    int Class;
}

ဒါကို inheritance လုပ္တယ္လို႔ ေခၚပါတယ္။ inheritance လုပ္လုိက္ျခင္းအားျဖင့္ People class ထဲက member data ကို Student class ထဲမွာ ျပန္ျပီ ေၾကျငာေပးေနစရာ မလုိေတာ့ပါဘူး။ ဒါေပမယ့္ ဒီေနရာမွာ အေရးၾကီးတဲ႔ အခ်က္တစ္ခ်က္ကို သိထားဖို႔ လိုပါေသးတယ္။ ဒီလိုဗ်ာ ကြၽန္ေတာ္တို႔ မိဘရဲ႕ ပိုင္ဆိုင္မႈအားလံုး ကြၽန္ေတာ္တို႔ရမလား၊ မရပါဘူး သူတို႔ ကိုယ္ပိုင္အတြက္ သိမ္းထားတာေတြလည္း ရွိနိုင္ပါတယ္။ C# language မွာလဲ အဲ့ဒီလိုမ်ိဳး ခြဲျခားဖို႔အတြက္ ကြၽန္ေတာ္တို႔ Access Modifier ဆိုတာကို သိဖို႔လိုအပ္လာပါတယ္။ C# language မွာ access modifier ၅ မ်ိဳးရွိပါတယ္။ အဲ့ဒါေတြ ကေတာ့

-       public                            ( အမ်ားသံုး )

-       protected                       ( မိမိႏွင့္child ေတြသံုး )

-       private                          ( မိမိကိုယ္တိုင္သံုး )

-       internal                         ( library တူအတြင္းသံုး )

-       protected internal           ( child ျဖစ္လွ်င္၄င္း၊ library တူလွ်င္၄င္း သံုး )

စသည္တို႔ ျဖစ္ပါတယ္။ အေပၚက example People class ေလးမွာ ကြၽန္ေတာ္တို႔ access modifier မထည့္ေပးလိုက္ပါဘူး။ ဒါဆိုရင္ default အေနနဲ႔ private ပါ။ ဒါေၾကာင့္ People class ထဲက member data သံုးခုက people class အတြင္းမွာပဲ သံုးခြင့္ရွိပါတယ္။ Student မွာ သံုးလို႔ မရပါဘူး။ အခုကြၽန္ေတာ္တို႔က Student class ထဲကေနပါ သံုးခြင့္ရခ်င္တာျဖစ္လို႔ protected member အျဖစ္ေၾကျငာေပးရမွာပါ။

class People
{
    protected string Name;
    protected int Age;
    protected string Address;
}

Polymorphism အသြင္ေျပာင္းျခင္းဆိုတာကေရာ???

ကြၽန္ေတာ္တို႔ ရပ္ကြက္ေတြမွာ လုပ္ေလ့ရွိတယ္ဗ်ာ တခါတေလ ရပ္ကြက္ရံုး ကေနျပီးေတာ့ တစ္အိမ္ကို လူတစ္ေယာက္ႏႈန္း အစည္းအေ၀းတက္ရမယ္တို႔ ဘာတို႔ ၾကံဳဖူးမွာေပါ့။ ဟုတ္ကဲ႔ ရပ္ကြက္ရံုးက ေခၚတာက လူတစ္ေယာက္လို႔ ေခၚတာပါ တနည္းအားျဖင့္ people class ကို ေခၚတာပါ။ အဲ့ဒါကို အိမ္မွာ ရွိေနတဲ႔ ေက်ာင္းသားတစ္ေယာက္က သြားတက္လို႔ မရဘူးလား၊ ရပါတယ္။ Teacher တစ္ေယာက္သြားတက္မယ္ဆိုလို႔လဲ ရပါတယ္။ Teacher ကလည္း people တစ္ေယာက္ပဲ ျဖစ္လို႔ပါ။ ဒါေပမယ့္ Student ပဲ သြားသည္ျဖစ္ေစ၊ Teacher ပဲသြားသည္ျဖစ္ေစ၊ ဒါမွမဟုတ္ People ကိုယ္တိုင္ပဲ သြားသည္ျဖစ္ေစ၊ အားလံုးကို People လို႔ပဲ ျမင္ပါတယ္။ အားလံုး အခြင့္အေရးတန္းတူပါပဲ။ Student မို႔ အခြင့္အေရးပိုရမလား မရပါဘူး။ အိုေက အဲ့ဒီလိုမ်ိဳး People ကိုေခၚတာကို Stuent သြားလိုက္တာကို အသြင္ေျပာင္းလဲျခင္း ( polymorphism ) လို႔ ေခၚပါတယ္။

static void Main()
{
    People p;
    p = new Student();
}

Polymorphism မွာ သတိထားရမည့္ အခ်က္ကေတာ့ child ကို parent အသြင္ေျပာင္းနိုင္ေပမယ့္ parent ကိုေတာ့ child အျဖစ္ေျပာင္းလို႔ မရပါဘူး။ ဆိုလိုတာကေတာ ေက်ာင္းသားအားလံုး စာေမးပြဲလာေျဖပါဆိုျပီး ေခၚတာကို အိမ္မွာ ရွိတဲ႔ လူၾကီးေတြသြားေျဖလို႔ ရမလား မရပါဘူး၊ ဒီသေဘာပါ။ Student ကိုေတာင္းရင္ေတာ့ People ေပးလို႔ မရပါဘူး၊ Student ပဲ ေပးမွ ရမွာပါ။

Data Hiding

Data hiding ဆိုတာကေတာ့ ကြၽန္ေတာ္တို႔ အိမ္မွာ မိသားစုပိုင္ဆိုင္မႈေတြကို တျခားလူေတြသိေအာင္ ထုတ္ေၾကျငာေလ့ရွိလား? မရွိပါဘူး တိတ္တိတ္ေလးပဲ သိမ္းထားေလ့ရွိပါတယ္။ ဒီသေဘာပါပဲ class ေတြထဲမွာရွိတဲ႔ member data ေတြကိုလည္း အျပင္ကေန ေခၚလို႔မရေအာင္ private လုပ္ထားျခင္းကို data hiding လို႔ ေခၚပါတယ္။ ဥပမာဗ်ာ အခု student class ထဲမွာ roll နဲ႔ class ပါတယ္မလား၊ အဲ့ဒီ member data ေတြကို အျပင္ကေန ေခၚသံုးလို႔ မရပါဘူ။ ဘာလို႔လဲဆိုေတာ့ private member data ေတြ ျဖစ္လို႔ပါ။ ဒီလုိမ်ိဳး class member data ေတြကို private အျဖစ္ပဲ ေၾကျငာတာကို Data Hiding လို႔ေခၚပါတယ္။

Encapsulation

Encapsulation ဆိုတာကေတာ့ ကြၽန္ေတာ္တို႔ hide လုပ္ထားတဲ႔ data ထဲက လိုအပ္တဲ႔ dataေတြကို function ေတြကေနေသာ္လည္းေကာင္း၊ property ေတြကေနတဆင့္ေသာ္လည္းေကာင္း၊ အသံုးျပဳနိုင္ဖို႔အတြက္ စီမံေပးျခင္းပဲ ျဖစ္ပါတယ္။ ကြၽန္ေတာ္တို႔ C# မွာေတာ့ member data ေတြကို ကိုယ္စားျပဳဖို႔အတြက္ property ေတြကိုသံုးေလ့ရွိပါတယ္။ ဒီလိုမ်ိဳးပါ..

class Student : People
{
    	int Roll;
    	int Class;
	public int RollNo
	{
		get
		{
			return Roll;
		}
		set
		{
			Roll = value;
		}
	}
	public int ClassID
	{
		get
		{
			return Class;
		}
		set
		{
			Class = value;
		}
	}
}
Older Posts »

Theme: Silver is the New Black. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.