简体   繁体   English

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

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

UPDATE: I've managed to fix my problem. 更新:我已经设法解决了我的问题。 Using the code below, I moved my MessageBox AFTER my XML saving and changed the Timer from 100ms to 400ms. 使用下面的代码,在保存XML之后移动了MessageBox,并将Timer从100ms更改为400ms。 I now have 1 box appear, thank god. 我现在有1个盒子出现,感谢上帝。 Although If anyone has a short cut to updating a single value (ActReminded) in the List array(ActListTask), that'd be great to know. 尽管如果有人在更新列表数组(ActListTask)中的单个值(ActReminded)方面有捷径,那真是太好了。

I'm having a little issue with displaying the MessageBox. 我在显示MessageBox时遇到了一些问题。 Show inside a timer without it spamming me. 在计时器内部显示,不会向我发送垃圾邮件。 Here's the part of the code I've been working with: 这是我一直在使用的代码部分:

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

I actually decided I may want to hold onto the reminder status, whether it has been shown or not as I wouldn't want a repeated reminder every time the program is opened. 实际上,我决定不管显示是否显示,都希望保留提醒状态,因为我不想每次打开程序时都重复提醒。 Since I don't know of a way to update an individual part of ActTaskList I just re-added it, and then deleted the original. 由于我不知道一种更新ActTaskList单个部分的方法,因此我只是重新添加了它,然后删除了原来的部分。 This code manages to recognise that if it happens, it will change the reminder status from false, to true; 该代码设法识别出,如果发生,它将提醒状态从false更改为true; after I've Ok'ed all the spam. 确定所有垃圾邮件之后。 So it will stop the MessageBox once I've managed to closed all the Messageboxes. 因此,一旦我设法关闭所有消息框,它将停止消息框。 However, it doesn't stop the spam. 但是,它不会阻止垃圾邮件。 Would it be anything to do with the fact I've set the timer to 100ms? 我将计时器设置为100毫秒与这有什么关系吗? Or could their be an alternative way to make the messagebox appear without it being inside the timer? 还是它们可以成为使消息框不出现在计时器内的另一种方式?

The odds of the current time lining up exactly to the second what is happening in your loop is small. 当前时间精确到秒的几率很小。 Why not treat newDateTime as a cut off point and just set a flag? 为什么不将newDateTime视为截止点并仅设置标志?

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

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

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

Can you do something like this? 你可以做这样的事情吗?

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

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

You say you've already tried a boolean indicating the message has already been shown, I'm assuming because the code probably looked like it did below. 您说您已经尝试过一个布尔值,指示消息已经显示,我认为是因为代码可能看起来像下面那样。

void TimerLoop()
{
    bool msgAlreadyShown;

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

The problem with that code is that the bool will be set to false each time the function is called by the timer. 该代码的问题在于,每次计时器调用函数时,布尔值都将设置为false。 You haven't posted much code, but you've at least stated what you're trying to accomplish, a timer that checks if a reminder should be presented to the user. 您没有发布太多代码,但是至少已经说明了要完成的工作,这是一个计时器,用于检查是否应向用户显示提醒。

I'm about to make some wild guesses about how you've put together your software, there's a good chance it's way off, but I hope it might point you in the right direction. 我将对您如何组合软件进行一些大胆的猜测,很有可能它已经走了,但是我希望它可以为您指明正确的方向。 You could have some sort of reminder class like this: 您可能会有这样的提醒类:

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

I'm assuming you might want to have multiple reminders that can be checked for in the timer loop, so your timer loop could look something like: 我假设您可能想在计时器循环中检查多个提醒,因此您的计时器循环可能类似于:

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

This is a pretty naive implementation, since you probably don't want to hold onto the reminders for forever and the reminders are never removed from the _activeReminders list, but you essentially just need to add some sort of state to determine if the reminder has already been shown. 这是一个非常幼稚的实现,因为您可能不想永远保留提醒,并且这些提醒永远不会从_activeReminders列表中删除,但是您基本上只需要添加某种状态来确定提醒是否已经存在被显示。

Of course, this isn't a complete example either, since I never new up the _activeReminders field or add anything to it, but I think this might help get the idea of what you need to do across. 当然,这也不是一个完整的示例,因为我从未新建_activeReminders字段或在其中添加任何内容,但是我认为这可能有助于您了解需要做的事情。 Also, you might not care about multiple reminders, and your timer code could look nothing like this. 另外,您可能不关心多个提醒,并且您的计时器代码可能看起来像这样。 The main idea was to show you how you can keep track of the state of a reminder, and tailor it to your own code. 主要思想是向您展示如何跟踪提醒的状态,并将其定制为自己的代码。 The above was just an example. 以上仅是示例。

Also, I haven't actually tested it, so treat it more like pseudocode than anything else. 另外,我还没有真正测试过它,因此将它像伪代码一样对待。 However, the logic is sound, and should it should only cause the message box to appear once. 但是,逻辑是合理的,应该只使消息框出现一次。

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

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