winform中一个窗口关闭后在主窗口上自动刷新显示的数据。谢谢

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了winform中一个窗口关闭后在主窗口上自动刷新显示的数据。谢谢相关的知识,希望对你有一定的参考价值。

在主窗体写:

 

form2 frm=new form2;
    if (frm.ShowDialog() == DialogResult.OK)
    
         //在form2关闭了,并且是OK的时候才执行
    
    
    //然后在form2窗体的确定按钮事件里写,这样在点击form2的确定键后关闭form2提  
    //示主窗体你点击的是确定键,
    this.DialogResult = DialogResult.OK;
    this.Close();

追问

谢谢你哈,能给我一个很简简单单的完成的例子吗?初学者

追答

没写实例吖,自己多研究研究 便于记忆。 多看看书 C#入门经典 不错,网上很多电子书。

参考技术A 子窗口关闭的时候,传递状态给主窗口 参考技术B 用委托和事件 在子窗体里面顶一个委托和事件,很简单的 不清楚联系我追问

还是不清楚哦。谢谢

在另一个线程上终止窗口

【中文标题】在另一个线程上终止窗口【英文标题】:Terminate Window on another thread 【发布时间】:2021-09-16 02:46:34 【问题描述】:

我有一个简单的 C# winform 应用程序,我在其中生成了一个新线程来显示另一个 winform。一个过程完成后,我想使用下面的代码关闭该表单。我遇到的问题是,当我调用busyForm.BeginInvoke 时,它绕过了空检查并抛出错误。如何在另一个线程中正确关闭winform?

static Indicator busyForm; 

public static async Task Execute()
        
            Thread busyIndicatorthread = new Thread(new ThreadStart(()=>FormThread()));
            busyIndicatorthread.SetApartmentState(ApartmentState.STA);
            busyIndicatorthread.Start();
        
        
           private static void FormThread()
        
            busyForm = new Indicator();
            busyForm.Closed += (sender2, e2) => busyForm.Dispatcher.InvokeShutdown();
            Dispatcher.Run();
        

public static Task Execute()
  
    Thread busyIndicatorthread = new Thread(new ThreadStart(()=>FormThread(hwind)));
            busyIndicatorthread.SetApartmentState(ApartmentState.STA);
            busyIndicatorthread.Start();
            
    // dos some stuff
            
     if (busyForm != null)
        
            busyForm.BeginInvoke(new System.Action(() => busyForm.Close())); <--- throw null error
            busyForm = null;
        

【问题讨论】:

拥有多个 UI 线程是非常不寻常的。你确定要走那条路吗? where I spawn a new thread to show another winform. 为什么?没有应用程序这样做,甚至不需要这样做。在所有应用程序中,忙碌和进度对话框都是由 UI 线程生成的。可能阻塞的操作在后台执行,例如在后台线程中或使用Task.Run。 UI 使用事件或回调进行更新,例如使用 Progress&lt; T&gt; 【参考方案1】:

那是因为在调用.Close() 方法之前,时间已经过去,不能确定busyForm 是否存在。 事实上,有可能在new System.Action(() =&gt; busyForm.Close() 线程启动时,您的主线程转到busyForm = null;

您可以尝试将 null 移动到辅助线程。

    if (busyForm != null)
    
       busyForm.BeginInvoke(new System.Action(() =>
        
          lock(busyForm)
            busyForm.Close();
            busyForm = null;
          
       ));         
    

【讨论】:

你永远不应该对可能变为空的东西使用锁。锁定空对象会抛出 ArgumentNullException - 并不是真正的改进。【参考方案2】:

几乎没有应用程序启动另一个消息泵来显示通知。这不是必需的。在所有应用程序中,忙碌和进度对话框都是由 UI 线程生成和显示的。可能阻塞的操作在后台执行,例如在后台线程中或更好,使用async/await 和Task.Run。 UI 使用事件或回调进行更新,例如使用 Progress< T> 类。

不过,在这种情况下,似乎只需要在长时间运行的任务之前显示一个表单并在之后隐藏它:

public async void btnDoStuff_Async(object sender, EventArgs args)

    //Disable controls, display indicator, etc
    btnDoStuff.Enabled=false;
    using var busyForm = new Indicator();
    busyForm.Show();

    try
    
        var result=await Task.Run(()=> ActuallyDoStuffAndReturnResult());

        //Back in the UI form
        //Do something with the result
    
    finally
    
        //Close the busy indicator, re-enable buttons etc.
        busyForm.Close();
        btnDoStuff.Enabled=true;
    

finally 块可确保 UI 已启用,并且即使在出现错误时也会隐藏忙碌的表单。

20 多年前,一些 Visual Basic 6 应用程序确实启动了另一个 Window 消息泵来充当“服务器”。 Visual Basic 6 线程非常很古怪,所以人们使用各种技巧来解决它的限制。

【讨论】:

【参考方案3】:

当你编写这段代码时:

        busyForm.BeginInvoke(new System.Action(() => busyForm.Close())); <--- throw null error
        busyForm = null;

它的执行顺序几乎可以肯定是这样的:

        busyForm = null;
        busyForm.Close();

难怪你得到一个空引用异常!

只需在调用中将表单设置为 null。这样就解决了。

然而,正确的做法是按照 Panagiotis Kanavos 的建议。

【讨论】:

以上是关于winform中一个窗口关闭后在主窗口上自动刷新显示的数据。谢谢的主要内容,如果未能解决你的问题,请参考以下文章

在winform中,关闭窗口时刷新父窗口(原来打开此窗口的窗口)

C# winform 关闭窗体后在打开 如何让打开的窗体还是原窗体 且打开的窗体还是原状态

C#winform中在一个主窗体中打开几个子集窗口,如何让子集窗口在主窗体中平均分布

请教winform刷新问题

在wpf或winform关闭子窗口或对子窗口进行某个操作后刷新父窗口

php 窗体关闭以后怎样自动刷新父页面