繁体   English   中英

让MessageBox出现一次(计时器内的代码)

[英]Have MessageBox appear once (code inside timer)

更新:我已经设法解决了我的问题。 使用下面的代码,在保存XML之后移动了MessageBox,并将Timer从100ms更改为400ms。 我现在有1个盒子出现,感谢上帝。 尽管如果有人在更新列表数组(ActListTask)中的单个值(ActReminded)方面有捷径,那真是太好了。

我在显示MessageBox时遇到了一些问题。 在计时器内部显示,不会向我发送垃圾邮件。 这是我一直在使用的代码部分:

public class ActiveTasks
    {
        //Properties here
    }

public List<ActiveTasks> ActTaskList = new List<ActiveTasks>();

for (int i = 0; i < ListActive.Items.Count; i++)
        {
            if (DTime.Date == newDateTime.Date)
            {
                if (newDateTimeLeft.CompareTo(TimeSpan.Zero) <= 0 && ActTaskList[i].ActReminded != "true")
                {
                    MessageBox.Show("!!!!");
                    ActTaskList.Add(new ActiveTasks()
                    {
                        ActTitle = ActTaskList[i].ActTitle,
                        ActDesc = ActTaskList[i].ActDesc,
                        ActDate = ActTaskList[i].ActDate,
                        ActTime = ActTaskList[i].ActTime,
                        ActStatus = ActTaskList[i].ActStatus,
                        ActReminded = "true",
                        ActRepeat = ActTaskList[i].ActRepeat
                    });

                    ListActive.Items.RemoveAt(i);

                    ActTaskList.RemoveAt(i);

                    XDocument XmlActTasks = GenerateActiveListToXML(ActTaskList);
                }
            }
        }

实际上,我决定不管显示是否显示,都希望保留提醒状态,因为我不想每次打开程序时都重复提醒。 由于我不知道一种更新ActTaskList单个部分的方法,因此我只是重新添加了它,然后删除了原来的部分。 该代码设法识别出,如果发生,它将提醒状态从false更改为true; 确定所有垃圾邮件之后。 因此,一旦我设法关闭所有消息框,它将停止消息框。 但是,它不会阻止垃圾邮件。 我将计时器设置为100毫秒与这有什么关系吗? 还是它们可以成为使消息框不出现在计时器内的另一种方式?

当前时间精确到秒的几率很小。 为什么不将newDateTime视为截止点并仅设置标志?

//Declare this outside of the loop
bool hasDisplayed = false;

//Inside the timer event handler
if (!hasDisplayed && DateTime.Now >= newDateTime)
{
    hasDisplayed = true;

    MessageBox.Show("!!!!!!!!!!!!!");
}

你可以做这样的事情吗?

Action message = () => MessageBox.Show("!!!!!!!!!!!!!"));
object lockOb = new object();

void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    lock(lockOb)
        if(null != message)
        {
            message();
            message = null;
        }
}

您说您已经尝试过一个布尔值,指示消息已经显示,我认为是因为代码可能看起来像下面那样。

void TimerLoop()
{
    bool msgAlreadyShown;

    if(!msgAlreadyShown)
    {
        MessageBox.Show("!!!!!!!");
    }
    // Other work in your timer function
}

该代码的问题在于,每次计时器调用函数时,布尔值都将设置为false。 您没有发布太多代码,但是至少已经说明了要完成的工作,这是一个计时器,用于检查是否应向用户显示提醒。

我将对您如何组合软件进行一些大胆的猜测,很有可能它已经走了,但是我希望它可以为您指明正确的方向。 您可能会有这样的提醒类:

public class Reminder
{
    string Message { get; set;}
    DateTime Alarm { get; set; } 
    bool IsDismissed { get; set; }
}

我假设您可能想在计时器循环中检查多个提醒,因此您的计时器循环可能类似于:

private List<Reminder> _activeReminders; // A list of reminders

void TimerLoop(object s, ElapsedEventArgs e)
{
    lock(_activeReminders) 
    {
        var now = DateTime.Now;
        foreach(var reminder in _activeReminders)
        {
            // only run this code if the time has passed and it hasn't already
            // been shown
            if(now.CompareTo(reminder.Alarm) >= 0 && !reminder.IsDismissed)
            {
                MessageBox.Show(reminder.Message);
                reminder.IsDismissed = true;
            }
        }
    }
}

这是一个非常幼稚的实现,因为您可能不想永远保留提醒,并且这些提醒永远不会从_activeReminders列表中删除,但是您基本上只需要添加某种状态来确定提醒是否已经存在被显示。

当然,这也不是一个完整的示例,因为我从未新建_activeReminders字段或在其中添加任何内容,但是我认为这可能有助于您了解需要做的事情。 另外,您可能不关心多个提醒,并且您的计时器代码可能看起来像这样。 主要思想是向您展示如何跟踪提醒的状态,并将其定制为自己的代码。 以上仅是示例。

另外,我还没有真正测试过它,因此将它像伪代码一样对待。 但是,逻辑是合理的,应该只使消息框出现一次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM