委托调用form的show时,未创建窗口句柄前不能调用beginInvoke

本文探讨在WinForms应用程序中使用WebAPI时遇到的问题,特别是在首次显示窗体时因未创建窗口句柄而引发的错误。通过分析,提供了一种解决方案,即利用已显示的窗体作为代理来调用委托,从而避免错误并成功展示目标窗体。

委托调用form的show时,未创建窗口句柄前不能调用beginInvoke

重新写一下,在工作中遇到一个场景,运行一个form程序,

  1. run 一个Sign的form,和360似得在桌面上一个图标;
  2. form程序中托管了一个webapi,webapi接收到请求时,要show form1;
  3. 但是这个form1从来没有show过,只是实例化了;
    然后在第一次show的时候报错了 没有创建窗口句柄。

托管的WebApi

var config = new HttpSelfHostConfiguration("http://localhost:8081");
config.Routes.MapHttpRoute(
     name: "API Default",
     routeTemplate: "api/{controller}/{id}",
     defaults: new { id = RouteParameter.Optional });
 var server = new HttpSelfHostServer(config);
 server.OpenAsync().Wait();

ApiController 接收数据

 /// <summary>
/// 收到数据,更新界面
/// </summary>
public static Action<PLCTask> AddTask;
[HttpPost]
public IHttpActionResult Post([FromBody]PLCTask task)
{
    
    Result<object> result = new Result<object>();
    if (tasks != null)
    {
       Task.Run(() => AddTask?.Invoke(task));
    }
    return Ok(result);
}

然后form1中实现controller中定义的委托,但是在执行委托时,show不出来,呵呵,调试了一下,InvokeRequired=false,直接跳过了。

 AccessStationTaskController.AddTask = add;
 
 public void add(PLCTask task)
 {
      refreshData(task);
      if (this.InvokeRequired)
      {
          this.BeginInvoke(new Action(() => this.Visible = true));
      }
  }

然后强行让程序走BeginInvoke方法时,报错“在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke”;
原来,form在实例化后是没有创建窗口句柄的,必须在show后才会创建窗口句柄
查看form此时的IsHandleCreated也是false状态。
委托show窗体之前可以判断一下IsHandleCreated 或者 InvokeRequired

解决办法:
然而并没有找到除了show之外的创建窗口句柄的方法(手动狗头,在线卑微求助),有知道的大神麻烦指教下,哈哈 谢谢
曲线救国:
既然form在show后才能有窗口句柄,那么第一次show的时候在form1内部定义委托show出来不太可能了,
那么,我找一个已经show出来的Sign定义一个form1的字段,然后调用Sign的委托,然后在委托中show出form1就可以了
form1中定义一个委托,重写add方法:

public Action ShowForm;
public void add(PLCTask task)
{
    refreshData(task);
    if (this.InvokeRequired)
    {
        this.BeginInvoke(new Action(() => this.Visible = true));
    }
    else
    {
        ShowForm?.Invoke();
    }
}

然后在Sign中实现form1的这个委托

private static Form1 form;
public Sign()
 {
     InitializeComponent();
     form = new Form1();
     form.ShowForm = showForm;
 }
 private void showForm()
 {
     if (InvokeRequired)
     {
         this.BeginInvoke(new Action(() => { form.Show(); }));
     }
 }

ok,可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值