views:

263

answers:

1

Hello,

I develop small application in C# but I've problem with events. My form have controlState property which describe current state of application. When application is in SEARCH state and I press enter it exec both KeyDown_Search and KeyDown_Idle method. When I add MessageBox.Show("anything"); at the end of KeyDown_eventManager problem doesn't exists - it exec only KeyDown_Search method.
What can I do to solve this problem?

enum ControlState {NO_SHOW, IDLE, SEARCH}

private ControlState controlState;

protected override void OnShown(EventArgs e)
{
  this.controlState = ControlState.IDLE;
  this.KeyDown += new KeyEventHandler(KeyDown_eventManager);
}

void KeyDown_eventManager(object sender, KeyEventArgs e)
{
  switch (this.controlState)
  {
    case ControlState.SEARCH:
      this.KeyDown_Search(sender, e);
      break;
    case ControlState.NO_SHOW:
    case ControlState.IDLE:
      this.KeyDown_Idle(sender, e);
      break;
  }
}

void KeyDown_Search(object sender, KeyEventArgs e)
{
  switch (e.KeyCode)
  {
    case Keys.Enter:
      this.textContent = this.db.searchList(this.textSearch);
      this.textSearch = null;
      this.controlState = ControlState.IDLE;
      break;
  }
  this.draw();
}

void KeyDown_Idle(object sender, KeyEventArgs e)
{
  switch (e.KeyCode)
  {
    case Keys.Enter:
      this.controlState = ControlState.NO_SHOW;
      break;
  }
  this.draw();
}

Update: I add all application code. Maybe it's help to find solution.

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 dbConnector;
using DX = Microsoft.DirectX;
using D3D = Microsoft.DirectX.Direct3D;

namespace dbConnector
{
    public class dbText
    {
        public dbText()
        {

        }

        public string searchList(string keyword)
        {
            return "there will be connection to db";
        }
    }
}

namespace Rzutnik
{
    enum ControlState
    {
        NO_SHOW, IDLE, SEARCH
    }

    public partial class Display : Form
    {
        private D3D.Device device;
        private dbText db;
        private ControlState controlState;
        private D3D.Font textFont;
        private D3D.Font textSearchFont;
        private Rectangle textRect;
        private int textPosition;
        private bool textScrollingUp;
        private int textJump;
        private Timer textScrollingTimer;
        private Timer textAutocomplete;
        private int textScrollingTimerInterval;
        private string textContent;
        private string textSearch = null;

        public Display()
        {
            InitializeComponent();
            this.controlState = ControlState.IDLE;
            this.InitializeDb();
            this.InitializeDevice();
            this.textInitialize();
            this.KeyDown += new KeyEventHandler(KeyDown_eventManager);
            this.KeyUp += new KeyEventHandler(KeyUp_eventManager);
            this.KeyPress += new KeyPressEventHandler(KeyPress_eventManager);
            this.Paint += new PaintEventHandler(DisplayPaint);
            this.ResizeEnd += new EventHandler(DisplayResizeEnd);
        }

        protected void InitializeDb()
        {
            this.db = new dbText();
        }

        protected void InitializeDevice()
        {
            D3D.PresentParameters presentParams = new D3D.PresentParameters();
            presentParams.BackBufferFormat = D3D.Format.R5G6B5;
            presentParams.Windowed = true;
            presentParams.SwapEffect = D3D.SwapEffect.Discard;

            this.device = new D3D.Device(0, D3D.DeviceType.Hardware, this, D3D.CreateFlags.SoftwareVertexProcessing, presentParams);
        }

        void KeyDown_eventManager(object sender, KeyEventArgs e)
        {
            switch (this.controlState)
            {
                case ControlState.SEARCH:
                    this.KeyDown_Search(sender, e);
                    break;
                case ControlState.NO_SHOW:
                    this.KeyDown_Idle(sender, e);
                    break;
                case ControlState.IDLE:
                    this.KeyDown_Idle(sender, e);
                    break;
            }

            //MessageBox.Show("anything");
        }

        void KeyUp_eventManager(object sender, KeyEventArgs e)
        {
            switch (this.controlState)
            {
                case ControlState.NO_SHOW:
                case ControlState.IDLE:
                    this.KeyUp_Idle(sender, e);
                    break;
            }
        }

        void KeyPress_eventManager(object sender, KeyPressEventArgs e)
        {
            switch (this.controlState)
            {
                case ControlState.NO_SHOW:
                case ControlState.IDLE:
                case ControlState.SEARCH:
                    this.KeyPress_Idle_Search(sender, e);
                    break;
            }
        }

        void KeyDown_Idle(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Up:
                    if (this.textScrollingTimer.Enabled == true)
                        return;
                    this.textStartScrollingUp();
                    break;
                case Keys.Down:
                    if (this.textScrollingTimer.Enabled == true)
                        return;
                    this.textStartScrollingDown();
                    break;
                case Keys.Enter:
                    this.controlState = ControlState.NO_SHOW;
                    break;
            }

            this.draw();
        }

        void KeyUp_Idle(object sender, KeyEventArgs e)
        {
            base.OnKeyDown(e);

            switch (e.KeyCode)
            {
                case Keys.Up:
                case Keys.Down:
                    this.textStopScrolling();
                    break;
            }

            this.draw();
        }

        void KeyDown_Search(object sender, KeyEventArgs e)
        {
            e.Handled = true;
            switch (e.KeyCode)
            {
                case Keys.Enter:
                    this.textContent = this.db.searchList(this.textSearch);
                    this.textSearch = null;
                    this.controlState = ControlState.IDLE;
                    System.Threading.Thread.Sleep(50);
                    break;
                case Keys.Back:
                    this.textSearch = this.textSearch.Substring(0, this.textSearch.Length - 1);
                    this.textAutocomplete.Stop();
                    this.textAutocomplete.Start();
                    if (this.textSearch.Length == 0)
                        this.controlState = ControlState.IDLE;
                    break;
            }
            this.draw();
        }

        void KeyPress_Idle_Search(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar != 8 && e.KeyChar != 13)
            {
                this.textSearch += e.KeyChar;
                this.textAutocomplete.Stop();
                this.textAutocomplete.Start();
                this.controlState = ControlState.SEARCH;
            }
        }

        public void drawSearch()
        {
            this.device.BeginScene();
            this.textSearchFont.DrawText(null, this.textSearch, new Point(10, this.ClientSize.Height - 10 - 9), Color.Red);
            this.device.EndScene();
        }

        public void drawText()
        {
            device.BeginScene();
            this.textFont.DrawText(null, this.textContent, this.textRect, D3D.DrawTextFormat.WordBreak, Color.White);
            device.EndScene();
        }

        public void draw()
        {
            device.Clear(D3D.ClearFlags.Target, Color.Black, 1.0f, 0);

            switch (this.controlState)
            {
                case ControlState.IDLE:
                    this.drawText();
                    break;
                case ControlState.SEARCH:
                    this.drawText();
                    this.drawSearch();
                    break;
            }

            device.Present();
        }

        void DisplayResizeEnd(object sender, EventArgs e)
        {
            this.textInitializeRectangleSize();
            this.draw();
        }

        void DisplayPaint(object sender, PaintEventArgs e)
        {
            this.draw();
        }

        private void textInitialize()
        {
            this.textPosition = 0;
            this.textJump = 3;
            this.textContent = null;

            this.textAutocomplete = new Timer();
            this.textAutocomplete.Interval = 100;
            this.textAutocomplete.Tick += new System.EventHandler(textAutocomplete_Tick);

            this.textScrollingTimer = new Timer();
            this.textScrollingTimerInterval = 1;
            this.textScrollingTimer.Interval = this.textScrollingTimerInterval;
            this.textScrollingTimer.Tick += new System.EventHandler(textScrollingTimer_Tick);

            this.textInitializeRectangleSize();
            this.textInitializeFont();
        }

        void textAutocomplete_Tick(object sender, System.EventArgs e)
        {
            this.textContent = this.db.searchList(this.textSearch.Trim());
            this.textAutocomplete.Stop();
            this.draw();
        }

        private void textInitializeRectangleSize()
        {
            this.textRect = new Rectangle(10, 10 + this.textPosition, this.ClientSize.Width - 20, this.ClientSize.Height - 20 + this.textPosition);
        }

        private void textInitializeFont()
        {
            System.Drawing.Font systemfont1 = new System.Drawing.Font("Arial", 12f, FontStyle.Regular);
            System.Drawing.Font systemfont2 = new System.Drawing.Font("Arial", 9f, FontStyle.Regular);
            this.textFont = new D3D.Font(this.device, systemfont1);
            this.textSearchFont = new D3D.Font(this.device, systemfont2);
        }

        void textScrollingTimer_Tick(object sender, System.EventArgs e)
        {
            if (this.textScrollingUp == true)
                this.textPosition -= this.textJump;
            else
                this.textPosition += this.textJump;

            this.textInitializeRectangleSize();
            this.draw();
        }

        private void textStartScrollingUp()
        {
            this.textScrollingUp = true;
            this.textScrollingTimer.Start();
        }

        private void textStartScrollingDown()
        {
            this.textScrollingUp = false;
            this.textScrollingTimer.Start();
        }

        private void textStopScrolling()
        {
            this.textScrollingTimer.Stop();
        }
    }
}
+2  A: 

My guess is that you add event listener in two places. Probably in the generated designer code as well as your OnShown method (and, btw, OnShown is an odd place to add event handlers).

erikkallen
Either that, or OnShown fires more than once
Sander Rijken
@Sander: it's fired only once, when the form is shown for the 1st time.
Groo
I don't think that problem is in add event in two places - when I add MessageBox.Show("anything"); it show only once.
zmszaman
Well, there are 3 alternatives: 1) The event fires twice, 2) You have omitted something important in the posted snipped, and 3) You have hit some strange compiler bug. 3) is very unlikely. Where did you add your MessageBox.Show() call?
erikkallen
at the end of KeyDown_eventManager method
zmszaman