双重执行

发布于 2024-08-16 09:45:11 字数 10625 浏览 7 评论 0原文

我用 C# 开发小型应用程序,但我遇到了事件问题。我的表单有 controlState 属性,它描述应用程序的当前状态。当应用程序处于 SEARCH 状态并且我按 Enter 键时,它会执行 KeyDown_Search 和 KeyDown_Idle 方法。当我添加 MessageBox.Show("anything"); 时在 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();
        }
    }
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

看透却不说透 2024-08-23 09:45:12

我的猜测是您在两个地方添加事件侦听器。可能在生成的设计器代码以及 OnShown 方法中(顺便说一句,OnShown 是添加事件处理程序的奇怪位置)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文