繁体   English   中英

如何在Windows应用程序.Net CF 3.5中显示/关闭加载表单

[英]How To Show / Close Loading Form In Windows Applications of .Net CF 3.5

我创建了智能设备应用程序(.Net CF 3.5),并创建了一个加载表单并命名为ModalLoadingUI ,在进行操作时必须显示此表单。 这种形式的源代码是:

public partial class ModalLoadingUI : Form
{

    public Form BackgroundForm { get; set; }

    public ModalLoadingUI()
    {
        InitializeComponent();
    }        

    private void ModalLoadingUI_Closed(object sender, EventArgs e)
    {
        if (BackgroundForm != null) BackgroundForm.Enabled = true;
    }        
}

在操作过程中,将显示此表格,例如:

private void btnShowLoading_Click(object sender, EventArgs e)
{
    loading = new ModalLoadingUI { BackgroundForm = this };
    this.Enabled = false;
    loading.CenterForm();
    loading.Show();

    try
    {
        Application.DoEvents();
        Thread.Sleep(2500);
    }
    catch (Exception)
    {
        throw;
    }
    finally
    {
        loading.Close();
    }
}

我可以使用ShowDialog()方法而不是Show()方法Show() ModalLoadingUI表单的实例吗? 并且在操作完成之后,然后加载关闭? 由于ShowDialog()方法之后的代码将无法运行。

我知道我可以显示通过另一个线程进行加载,并使用如下代码:

this.BeginInvoke(new Action(() => new ModalLoadingUI().ShowDialog()));

但这不是我想要的代码,因为我想在ModalLoadingUI实例上运行CenterForm()方法,并且在操作完成之后必须关闭“加载”。

基于上述内容,我如何显示/关闭加载表单( ModalLoadingUI )?

感谢和问候

ShowDialog是一个糟糕的选择,因为被调用的Form具有自己的消息泵并有效地阻止了调用者。

您想要的是一个UI元素,该元素可能涵盖中间部分并显示“正在工作”,并且可能会进行一些进度更新。 CF并非最适合此功能,但绝对有可能。 这是我如何解决此问题的方法:

  1. 创建无边框,没有控制框,没有最小化或最大化框的“加载”表单。 这样一来,它不仅可以全屏显示,而且可以定位。
  2. 创建加载表格,并展示在与调用它显示一些“服务”的方式Show ,然后等待来电者来完成。 这是基于立即执行后台处理的调用者定的-它不能位于UI线程上。

这是一些未编译的伪代码:

// this would go in some service-level class
public void ShowLoading(Func<bool> workToDo)
{
    using(var load = new LoadingForm())
    {
        var completed = new AutoResetEvent(false);
        new Thread(delegate
            {
                try
                {
                    workToDo();
                }
                finally
                {
                    completed.Set();
                }
            });

        // show the loading form
        load.Show();

        // wait for the background worker
        while (!completed.WaitOne(100))
        {
            // just keep waiting
            // the timeout allows the UI to update
            // if you want to update the loading form with progress
            // or whatever, do that here
        }
    }
}

呼叫者看起来像这样:

void Foo()
{
    // this is the "entry point"
    ShowLoading(MyWorker);
}

bool MyWorker()
{
    // do your long-running stuff here
}

如果您真的想花哨的话,可以在显示它之前先对其进行截屏,然后对其进行阴影处理,然后将其绘制在上面,以使“背景表单”看起来像已被禁用,但是我肯定会首先进行上述操作-先走之前你跑。

Pezman,

我已经找到了无需借助第三方工具(例如SlideUI )即可执行此操作的方法:

面板:

我在显示的表单上使用了隐藏面板。 如果需要在面板运行时禁用表单,则可以执行此操作。 缺点是,如果您有多个运行流程的表单,则必须在每个表单上都隐藏一个面板。 另外,要在面板上制作边框,您必须添加以下绘画功能:

Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
    Dim CurPanel As Panel = CType(sender, Panel)
    e.Graphics.DrawRectangle(New Pen(Color.Black), 0, 0, CurPanel.Width - 1, CurPanel.Height - 1)
End Sub

形成:

您可以使用表单,假设您从中触发操作的表单具有事件。
优点:可以在任何地方调用自包含类。缺点:没有简单的方法可以使它成为一个较小的居中窗口,必须声明事件,必须使用一种形式来控制操作更新。

这是一种实现方法:假设Form1触发了操作,而Form2是您的状态。

Form1(流程的所有者)将需要一个事件函数,如下所示:

Public Event UpdateStatus(ByVal NewVal As String)

然后,当某些事情发生时,它需要引发一个事件:

RaiseEvent UpdateStatus(NewValue)

Form2(状态更新)必须具有指向Form1的指针。 有几种方法可以执行此操作-您可以在new处分配,也可以稍后分配:

    Private WithEvents _pMain As Main

    Public Sub New(ByRef pMain As Main)

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        _pMain = pMain
    End Sub

    Private Sub StatUpdate(ByVal Status As String) Handles _pMain.UpdateStatus
        Label1.Text = Status
    End Sub

两种选择都无法满足您的需求,但其中一种解决方案可能会给您带来警告。

暂无
暂无

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

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