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

时间:2012-04-02 18:36:23

标签: c# c#-4.0

更新:我设法解决了我的问题。使用下面的代码,我在保存XML后移动了MessageBox,并将Timer从100ms更改为400ms。我现在有1个盒子出现,谢天谢地。虽然如果有任何人在List数组(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;在我发现所有垃圾邮件之后。因此,一旦我设法关闭所有Messagebox,它就会停止MessageBox。但是,它并没有阻止垃圾邮件。这与我将计时器设置为100毫秒的事实有关吗?或者它们是否可以使消息框显示而不在计时器内?

3 个答案:

答案 0 :(得分:1)

当前时间恰好与你的循环中发生的事情排成一行的几率很小。为什么不将newDateTime视为切断点并设置一个标志?

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

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

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

答案 1 :(得分:0)

你能做这样的事吗?

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

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

答案 2 :(得分:0)

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

void TimerLoop()
{
    bool msgAlreadyShown;

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

该代码的问题是每次定时器调用该函数时bool都将设置为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字段或添加任何内容,但我认为这可能有助于了解您需要做什么。此外,您可能不关心多个提醒,您的计时器代码可能看起来不像这样。主要想法是向您展示如何跟踪提醒的状态,并根据您自己的代码进行定制。以上只是一个例子。

另外,我还没有对它进行过测试,因此将其视为伪代码而不是其他任何东西。但是,逻辑是合理的,它应该只导致消息框出现一次。