2010-01-02 42 views
0

我在C#中开发小应用程序,但我遇到事件问题。我的表单具有描述当前应用程序状态的controlState属性。当应用程序处于SEARCH状态时,我按下Enter键可执行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 2010-01-02 14:46:33

+0

您应该在窗体的构造函数中附加'KeyDown'处理函数,而不是在'OnShown'中。在你的代码中查找“KeyDown_eventManager”,看看你没有连接两次处理程序。 – Groo 2010-01-02 14:53:31

+0

这是Windows窗体应用程序,我使用托管directx。 我将KeyDown处理程序移动到Form构造函数,但它不能解决我的问题。我在我的代码中查找KeyDown_eventManager的发生,但是我发现它只在2个地方 - 定义并附加 – zmszaman 2010-01-02 15:13:42

回答

2

我的猜测是你在两个地方添加了事件监听器。可能在生成的设计器代码以及OnShown方法中(和btw,OnShown是添加事件处理程序的奇怪地方)。

+0

要么是这样,要么是OnShown不止一次触发 – 2010-01-02 14:45:00

+0

@Sander:当表单第一次显示时,它只被触发一次。 – Groo 2010-01-02 14:51:03

+0

我不认为这个问题是在两个地方添加事件 - 当我添加MessageBox.Show(“任何”);它只显示一次。 – zmszaman 2010-01-02 14:55:56