cgraham720
cgraham720

Reputation: 147

Images not displaying on Winform.show c#

I have program that displays a "Loading" Winform when a button is pressed and disappears once the script needing to be run is complete.

When the button is pressed, the new form 'appears' however it displays none of the form information, such as the Logo and labels - only a blank/grey box. I've attempted changing the background colour and altering images however it is still displaying as blank form.

What I find to be most confusing is that this blank form displayed only appears blank when a specific CS. file is called within the button press; PDFMerge.CombineMultiblePDFs. If I try to display the Loading form within a different part of the program, e.g. when a different button is pressed, the form loads correctly as planned with all content.

Here is the blank form being displayed:

enter image description here

Here is the correct form being displayed on a different button or different form

enter image description here

Here is the code I am calling which displays the "blank" Winform.

     loadingPDF.Show(); // Show the loading form 
     string fileDate = DateTime.Now.ToString("dd-MM-yy");
     string fileTime = DateTime.Now.ToString("HH.mm.ss");
     string outcomeFolder = outputFolder;
     string outputFile = "Combined Folder " + fileDate + " @ " + fileTime + ".pdf";
     string outputFileName = Path.Combine(outcomeFolder, outputFile);

     // combines the file name, output path selected and the yes / no for pagebreaks. 
     PDFMerge.CombineMultiplePDFs(sourceFiles, outputFileName);
     loadingPDF.Hide(); // Hide the loading form 

If I replace the PDFMerge.Combine with a different within CS file, the Loading form displays correctly, which leads me to believe the issue is laying with the PDFMerge and when it is being called. Below is the code used within the PDFMerge;

public class PDFMerge
{
    public static void CombineMultiplePDFs(String[] fileNames, string outFile)
    {
        try
        {
            int pageOffset = 0;
            int f = 0;

            Document document = null;
            PdfCopy writer = null;

            while (f < fileNames.Length)
            {
                // Create a reader for a certain document
                PdfReader reader = new PdfReader(fileNames[f]);
                reader.ConsolidateNamedDestinations();

                // Retrieve the total number of pages
                int n = reader.NumberOfPages;
                pageOffset += n;
                if (f == 0)
                {
                    // Creation of a document-object
                    document = new Document(reader.GetPageSizeWithRotation(1));

                    // Create a writer that listens to the document
                    writer = new PdfCopy(document, new FileStream(outFile, FileMode.Create));

                    // Open the document
                    document.Open();
                }

                // Add content
                for (int i = 0; i < n;)
                {
                    ++i;
                    if (writer != null)
                    {
                        PdfImportedPage page = writer.GetImportedPage(reader, i);
                        writer.AddPage(page);
                    }
                }
                PRAcroForm form = reader.AcroForm;
                if (form != null && writer != null)
                {
                    //writer.CopyAcroForm(reader);
                    writer.Close();
                }
                f++;
            }

            // Close the document
            if (document != null)
            {
                document.Close();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

    }
}

I don't see what could be causing the clash with the form display, perhaps the Form isn't loading on time but i don't see how it works with some features and not with others. Any advice regarding the issue would be greatly appreciated. Thank you

Update 1: Additional code requested, Here is the code used to LoadingPDF form. I used Winforms to create the content on the form:

public partial class LoadingPDF : Form
{
    public LoadingPDF()
    {
        InitializeComponent();
    }

    private void LoadingPDF_Load(object sender, EventArgs e)
    { 
    // 
    }
}

Creating instance of the loadingPDF form in the file selection form

 // Declaring the 'loading' form when files are being combined.
    LoadingPDF loadingPDF = new LoadingPDF();

Upvotes: 1

Views: 720

Answers (1)

oppassum
oppassum

Reputation: 1775

Building on the comments, the PDFMerge.CombineMultiplePDFs() is cpu-locking your program, causing the thread to stop loading the form before it finishes. You can adapt your code like this:

public void ShowLoading()
{
 loadingPDF.Shown += loadingPDF_Shown;
 loadingPDF.Show(); // Show the loading form
}
public void loadingPDF_Shown(object sender, eventargs e)
{
 string fileDate = DateTime.Now.ToString("dd-MM-yy");
 string fileTime = DateTime.Now.ToString("HH.mm.ss");
 string outcomeFolder = outputFolder;
 string outputFile = "Combined Folder " + fileDate + " @ " + fileTime + ".pdf";
 // combines the file name, output path selected and the yes / no for pagebreaks. 
 PDFMerge.CombineMultiplePDFs(sourceFiles, outputFileName);
 loadingPDF.Hide(); // Hide the loading form 
}

Shown is the last event to trigger when a form is loaded. This should load your images before you start your cpu-intensive process.



An alternative would be to put your cpu-intensive process on another thread, to keep the UI thread clear. You can do that like this:

public void ShowLoading()
{
 loadingPDF.Show(); // Show the loading form 
 System.ComponentModel.BackgroundWorker worker = new BackgroundWorker();
 worker.DoWork += worker_DoWork;
 worker.RunWorkerCompleted += worker_RunWorkerCompleted;
 worker.RunWorkerAsync(); //Added missed line
}

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
   //anything you want to do AFTER the cpu-intensive process is done
   loadingPDF.Hide(); // Hide the loading form 
}
public void worker_DoWork(object sender, DoWorkEventArgs e)
{
 string fileDate = DateTime.Now.ToString("dd-MM-yy");
 string fileTime = DateTime.Now.ToString("HH.mm.ss");
 string outcomeFolder = outputFolder;
 string outputFile = "Combined Folder " + fileDate + " @ " + fileTime + ".pdf";
 string outputFileName = Path.Combine(outcomeFolder, outputFile);
 // combines the file name, output path selected and the yes / no for pagebreaks. 
 PDFMerge.CombineMultiplePDFs(sourceFiles, outputFileName);

}

Doing this with a background worker will keep your UI usable/clickable, and not make it freeze. Among other things, this allows for an animated loading form.

Upvotes: 1

Related Questions