将ui元素显示X秒钟或直到用户与其交互,然后检索用户输入

我正在研究一种可通过以下方式工作的小型工具:

  • 显示一系列图像
  • 在每个图像之后,显示一个答案窗口,用户可以在其中通过按下键盘上的按钮来输入答案
  • 答案窗口仅显示X秒钟,然后消失,然后将问题视为未回答

我所做的是让我做一个扩展UserControl的类

public partial class AnswerDialog : UserControl
{
    ...

    public void ShowAnswerDialog()
    {
        ResponseItemType = Settings.ItemType.ObjectType_NONE;
        this.Show();
        allowAnswer = true;
    }

    public void HideAnswerDialog()
    {
        allowAnswer = false;
        this.Hide();
    }

    ...

    private void buttonAnswerItemType0_Click(object sender,EventArgs e)
    {
        Setanswer(Settings.ItemType.ObjectType_0);
    }

    private void buttonAnswerItemType1_Click(object sender,EventArgs e)
    {
        Setanswer(Settings.ItemType.ObjectType_1);
    }

    public void AnswerDialog_KeyDown(object sender,KeyEventArgs e)
    {
        if (Settings.KeyCodeAnswer0 == e.KeyCode)
        {
            Setanswer(Settings.ItemType.ObjectType_0);
        }
        else if (Settings.KeyCodeAnswer1 == e.KeyCode)
        {
            Setanswer(Settings.ItemType.ObjectType_1);
        }
    }

    ...
}

它从父级接收键盘事件。

我有一堂课,我在这里控制显示图像和记录结果的顺序。 在此类中,我具有以下功能:

void AnswerThreadFunc(Object Param)
{
    AnswerDialog answerDialog = (AnswerDialog)Param;
    answerDialog.ShowAnswerDialog();
}

我是这样做的,所以我可以在主线程中使这个线程超时:

Thread answerThread = new Thread(AnswerThreadFunc); //create thread

answerThread.Start(_testWindow.GetanswerDialog()); //run thread

answerThread.Join(Settings.DurationResponseMs); //wait for thread with timout
_testWindow.GetanswerDialog().HideAnswerDialog(); //hide if window remained

Settings.ItemType response = _testWindow.GetanswerDialog().ResponseItemType;
item.GiveResponse(response);

但这将引发以下异常:

引发的异常:System.Windows.Forms.dll中的“ System.InvalidOperationException” System.Windows.Forms.dll中发生了类型为'System.InvalidOperationException'的未处理异常 跨线程操作无效:控件“ panelMainControl”从创建该线程的线程之外的其他线程访问。

谢谢。

l0123b0123 回答:将ui元素显示X秒钟或直到用户与其交互,然后检索用户输入

如果您进行搜索,该错误消息将给您带来很大的成功,但是却没有说谎。只有创建Winforms控件的线程才能与之交互。控件甚至具有一个属性,该属性会告诉您是否在正确的线程上(InvokeRequired),在该属性上进行搜索将返回大量信息,以帮助您确定是否在错误的线程上以及如何在正确的线程上调用线程来完成工作。

但是..我认为您已经使这一点变得复杂了。可以使用计时器在原始UI线程上完成所有操作-显示窗口并启动计时器,如果窗口隐藏,则停止计时器(在答案窗口上附加到合适的事件以了解其是否已隐藏-可能是VisibleChanged,但可能是FormClosing / ed)。如果计时器延迟3秒后触发计时器滴答事件,请隐藏窗口

编辑:实际上,让主窗口监视答案窗口的隐藏更为简单:让答案窗口包含一个计时器,该计时器在3秒钟后关闭答案窗口,并以load / show /无论如何形式启动计时器。任何一个应答按钮也会关闭该窗口。 ShowDialog它-发生两种情况之一-用户使用按钮并关闭窗口并设置了答案,或者计时器关闭了它却未设置答案。在showdialog之后,检索答案Property(将被设置或未设置)。如果要使用计时器向用户指示您还剩多少时间,请将其间隔设置为100,并在计时器刻度中将int从30倒数。当int达到0时,关闭答案窗口。将int/10.0放在标签中作为倒计时计时器

这里不需要多线程

本文链接:https://www.f2er.com/3112287.html

大家都在问