更新:我设法解决了我的问题。使用下面的代码,我在保存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毫秒的事实有关吗?或者它们是否可以使消息框显示而不在计时器内?
答案 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
字段或添加任何内容,但我认为这可能有助于了解您需要做什么。此外,您可能不关心多个提醒,您的计时器代码可能看起来不像这样。主要想法是向您展示如何跟踪提醒的状态,并根据您自己的代码进行定制。以上只是一个例子。
另外,我还没有对它进行过测试,因此将其视为伪代码而不是其他任何东西。但是,逻辑是合理的,它应该只导致消息框出现一次。