2010-01-02 6 views
0

Я разрабатываю небольшое приложение на C#, но у меня проблемы с событиями. Моя форма имеет свойство controlState, которое описывает текущее состояние приложения. Когда приложение находится в ПОИСКЕ, и я нажимаю кнопку ввода, выполняем оба метода KeyDown_Search и KeyDown_Idle. Когда я добавляю MessageBox.Show («ничего»); в конце проблемы KeyDown_eventManager не существует - он выполняет только метод KeyDown_Search.
Что делать, чтобы решить эту проблему?двойное выполнение

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(); 
} 

Обновление: я добавляю все код приложения. Может быть, это поможет найти решение.

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(); 
     } 
    } 
} 
+0

Предлагаем вам уточнить, является ли это форматом Windows, или если это UserControl ... или ...? Просто любопытно: почему вы переезжаете на OnShown? – BillW

+0

Вы должны приложить обработчик 'KeyDown' в конструкторе Form, а не внутри' OnShown'. Найдите свой код для появления «KeyDown_eventManager», чтобы увидеть, что вы не прикрепляете обработчик дважды. – Groo

+0

Это приложение Windows Form, и я использую управляемый directx. Перемещение обработчика KeyDown в конструктор формы, но это не решает мою проблему. Я ищу свой код для появления KeyDown_eventManager, но я нахожу его только в 2 месте - определение и прикрепление – zmszaman

ответ

2

Я предполагаю, что вы добавляете прослушиватель событий в два места. Вероятно, в созданном коде конструктора, а также в методе OnShown (и, btw, OnShown - нечетное место для добавления обработчиков событий).

+0

Либо это, либо OnShown срабатывает более одного раза –

+0

@Sander: он запускается только один раз, когда форма отображается в первый раз. – Groo

+0

Я не думаю, что проблема заключается в добавлении события в два места - когда я добавляю MessageBox.Show («ничего»); он отображается только один раз. – zmszaman

Смежные вопросы