Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过计时器事件显示登录表单_C#_Winforms - Fatal编程技术网

C# 通过计时器事件显示登录表单

C# 通过计时器事件显示登录表单,c#,winforms,C#,Winforms,我有一个我加载的主表单,当20分钟过去后,出于安全原因,我希望打开一个登录表单。我想确认正确的用户正在使用该软件,因此我考虑使用计时器,并给计时器20分钟的间隔。这是我的代码: private void timer1_Tick_1(object sender, EventArgs e) { foreach (Form f in Application.OpenForms) { if (f.Name != "login2") {

我有一个我加载的主表单,当20分钟过去后,出于安全原因,我希望打开一个登录表单。我想确认正确的用户正在使用该软件,因此我考虑使用计时器,并给计时器20分钟的间隔。这是我的代码:

private void timer1_Tick_1(object sender, EventArgs e)
{
    foreach (Form f in Application.OpenForms)
    {
        if (f.Name != "login2")
        {
            login2 lss = new login2();
            lss.ShowDialog(); 
        } 
    }
}
这里的问题是它每20分钟打开一次表单。这意味着,如果用户没有做任何事情,它只是一个接一个地显示一个登录表单,导致出现多个登录表单,这是我不希望看到的。我已经使用了循环,但它仍然不能正常工作。我不知道为什么

除此之外,我是否可以实现这样一个功能:如果表单空闲20分钟,则显示登录表单,id不空闲,则不显示登录表单??
它容易实现吗?我不想有任何复杂的情况,因为我是c#的新手,第一次做

如果您想要的是在一段时间的不活动后有效地将用户从应用程序中注销(或者至少给出注销的外观),那么您可以p/调用
GetLastInputInfo
,以满足您的需求

在计时器滴答声事件中,可以使用
GetLastInputInfo
返回上次检测到任何用户输入的时间。从Environment.TickCount中减去该值将得到一段不活动的时间。如果符合用户注销的条件,则可以显示登录表单

[DllImport("User32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

[StructLayout(LayoutKind.Sequential)]
internal struct LASTINPUTINFO
{
    public uint cbSize;
    public uint dwTime;
}

private void timer1_Tick_1(object sender, EventArgs e)
{
    var lastInputInfo = new LASTINPUTINFO();
    lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);

    GetLastInputInfo(ref lastInputInfo);

    int inactivityThreshold = 20 * 60 * 1000;

    if ((Environment.TickCount - lastInputInfo.dwTime) > inactivityThreshold)
    {
        login2 lss = new login2();
        lss.ShowDialog(); 
    } 
}

要解决表单多次出现的问题,只需使用布尔值指示用户当前是否登录,并将其作为是否显示登录表单的标准的一部分。

首先,添加一个函数重置计时器:

private void ResetTimer()
{
    timer1.Stop();
    timer1.Start();
}
调用时,它将重置计时器

其次,为了避免打开多个对话框,请使用同一个实例。将该登录表单的实例添加为类成员,然后使用它,而不是每次创建一个新实例:

login2 lss = new login2();
private void timer1_Tick(object sender, EventArgs e)
{
    if (!lss.Visible)
    {
        lss.ShowDialog();
        ResetTimer();
    }
}
如您所见,它将调用该对话框,并且仅当该对话框不可见时才调用,以避免出错。用户退出对话框后,它还会重置计时器

最后,要使其仅在“空闲”时倒计时,需要在有任何动作时重置计时器。对于表单中的每个控件,最简单的情况是鼠标移动和按键:

this.Controls.Cast<Control>().ToList().ForEach(c =>
{
    c.MouseMove += (s1, e1) => ResetTimer();
    c.KeyPress += (s1, e1) => ResetTimer();
});
this.Controls.Cast().ToList().ForEach(c=>
{
c、 MouseMove+=(s1,e1)=>ResetTimer();
c、 按键+=(s1,e1)=>ResetTimer();
});

在主窗体的加载事件中,这将为所有控件分配事件处理程序,但如果有嵌套控件,则必须使用递归来获取所有控件。

您的用户不会喜欢您。一点也不!为什么会这样?我首先想到,如果软件闲置20分钟,那么它将显示登录表单,但我如何实现这一点,所以我考虑定时器。你能建议我如何实现表单闲置20分钟,然后显示登录表单吗?这容易吗?所以每次用户返回到你的应用程序时,他们都必须再次登录?那会很快变老的。真的有必要吗?除非你在为全球热核战争编写控制器。。。可能不会,先生,我需要这个。你现在能帮我吗?好的,我删除了我的答案。这里是适合您的问题的相关主题,先生,您可以解释getlastinput信息吗。我从来没有听说过。你能给我举个例子吗?你可以在这里看到一个使用它的例子:我会在我的答案中添加一些基本的东西,所以它包含在so中。谢谢你,先生,最后一部分你能解释什么?这是哪一个,控制和所有的东西?它是linq吗?是的,它是Lambda表达式,以避免创建新方法的需要。c.MouseMove+=(s1,e1)=>ResetTimer();我听说lamda表达式的左边有输入,另一边有输出。。。你能告诉我为什么s1和e1被赋予了定时器的输入,因为该方法不接受任何参数吗?这只是一种声明匿名委托的简捷方法
s1
e1
是在后台创建的匿名函数的参数,它们都是必需的,因为事件处理程序的签名需要两个参数,但您不必使用它们。:)