Home > Net >  Writing to a rich text box in c#
Writing to a rich text box in c#

Time:11-24

New programmer here.

I've written an application to filter out password protected files from a large collection. It is working so far...

My problem is that I am trying to get the resulting paths what happened to them to write out into a text box. Maybe I am missing something completely obvious here, but I am getting the error:

CS0120 An object reference is required for the non-static field, method, or property MainWindow.SearchRunOutputBox

when attempting to assign values inside an updater method I wrote.

I am very confused as I had assumed that a rich text box, already present on the form, would be it's own object? Again, maybe I am just missing something obvious here...

Code below:

using Microsoft.VisualStudio.Services.CircuitBreaker;
using Spire.Pdf.Exporting.XPS.Schema;
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace Find_Move_PWP_PDF_s
{
    public partial class MainWindow : Form
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        public static void OutputBoxUpdater(string message, Color color)
        {  
            SearchRunOutputBox.SuspendLayout();
            SearchRunOutputBox.SelectionColor = color;
            SearchRunOutputBox.AppendText(message);
            SearchRunOutputBox.AppendText(Environment.NewLine);
            SearchRunOutputBox.ScrollToCaret();
            SearchRunOutputBox.ResumeLayout();
        }

Is the text box object not created when InitializeComonent() is called as the MainWindow starts?

Included designer.cs below:

partial class MainWindow
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.Windows.Forms.Label DirectoryPathLabel;
            System.Windows.Forms.Label CreateSubFoldersLabel;
            this.DirectoryPathInput = new System.Windows.Forms.TextBox();
            this.SearchStartButton = new System.Windows.Forms.Button();
            this.SearchProgressBar = new System.Windows.Forms.ProgressBar();
            this.MovePDFsButton = new System.Windows.Forms.Button();
            this.MovePDFsRunOutputBox = new System.Windows.Forms.RichTextBox();
            this.MovesProgressBar = new System.Windows.Forms.ProgressBar();
            this.SearchRunOutputBox = new System.Windows.Forms.RichTextBox();
            DirectoryPathLabel = new System.Windows.Forms.Label();
            CreateSubFoldersLabel = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // DirectoryPathLabel
            // 
            DirectoryPathLabel.AccessibleDescription = "DirectoryPathLabel";
            DirectoryPathLabel.AutoSize = true;
            DirectoryPathLabel.BackColor = System.Drawing.SystemColors.Window;
            DirectoryPathLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
            DirectoryPathLabel.Location = new System.Drawing.Point(14, 23);
            DirectoryPathLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            DirectoryPathLabel.Name = "DirectoryPathLabel";
            DirectoryPathLabel.Size = new System.Drawing.Size(370, 25);
            DirectoryPathLabel.TabIndex = 0;
            DirectoryPathLabel.Text = "Please enter the desired search directory.";
            // 
            // CreateSubFoldersLabel
            // 
            CreateSubFoldersLabel.AccessibleDescription = "CreateSubFoldersLabel";
            CreateSubFoldersLabel.AccessibleName = "CreateSubFoldersLabel";
            CreateSubFoldersLabel.AutoSize = true;
            CreateSubFoldersLabel.BackColor = System.Drawing.SystemColors.Window;
            CreateSubFoldersLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
            CreateSubFoldersLabel.Location = new System.Drawing.Point(14, 453);
            CreateSubFoldersLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            CreateSubFoldersLabel.Name = "CreateSubFoldersLabel";
            CreateSubFoldersLabel.Size = new System.Drawing.Size(725, 25);
            CreateSubFoldersLabel.TabIndex = 5;
            CreateSubFoldersLabel.Text = "Click here to move the password protected PDFs into subfolders labelled \"Locked\"."  
    "";
            // 
            // DirectoryPathInput
            // 
            this.DirectoryPathInput.AccessibleDescription = "DirectoryPathInput";
            this.DirectoryPathInput.Location = new System.Drawing.Point(424, 30);
            this.DirectoryPathInput.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
            this.DirectoryPathInput.Name = "DirectoryPathInput";
            this.DirectoryPathInput.Size = new System.Drawing.Size(822, 23);
            this.DirectoryPathInput.TabIndex = 1;
            // 
            // SearchStartButton
            // 
            this.SearchStartButton.AccessibleDescription = "SearchStartButton";
            this.SearchStartButton.Location = new System.Drawing.Point(1278, 23);
            this.SearchStartButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
            this.SearchStartButton.Name = "SearchStartButton";
            this.SearchStartButton.Size = new System.Drawing.Size(248, 30);
            this.SearchStartButton.TabIndex = 2;
            this.SearchStartButton.Text = "Start Search";
            this.SearchStartButton.UseVisualStyleBackColor = true;
            this.SearchStartButton.Click  = new System.EventHandler(this.SearchStartButton_Click);
            // 
            // SearchProgressBar
            // 
            this.SearchProgressBar.AccessibleDescription = "SearchProgressBar";
            this.SearchProgressBar.AccessibleName = "SearchProgressBar";
            this.SearchProgressBar.Location = new System.Drawing.Point(14, 257);
            this.SearchProgressBar.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
            this.SearchProgressBar.Name = "SearchProgressBar";
            this.SearchProgressBar.Size = new System.Drawing.Size(1512, 15);
            this.SearchProgressBar.TabIndex = 3;
            // 
            // MovePDFsButton
            // 
            this.MovePDFsButton.AccessibleDescription = "MovePDFsButton";
            this.MovePDFsButton.AccessibleName = "MovePDFsButton";
            this.MovePDFsButton.Location = new System.Drawing.Point(767, 453);
            this.MovePDFsButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
            this.MovePDFsButton.Name = "MovePDFsButton";
            this.MovePDFsButton.Size = new System.Drawing.Size(237, 25);
            this.MovePDFsButton.TabIndex = 6;
            this.MovePDFsButton.Text = "Move PDFs";
            this.MovePDFsButton.UseVisualStyleBackColor = true;
            // 
            // MovePDFsRunOutputBox
            // 
            this.MovePDFsRunOutputBox.AccessibleDescription = "MovePDFsRunOutputBox";
            this.MovePDFsRunOutputBox.AccessibleName = "MovePDFsRunOutputBox";
            this.MovePDFsRunOutputBox.BackColor = System.Drawing.Color.WhiteSmoke;
            this.MovePDFsRunOutputBox.Location = new System.Drawing.Point(14, 489);
            this.MovePDFsRunOutputBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
            this.MovePDFsRunOutputBox.Name = "MovePDFsRunOutputBox";
            this.MovePDFsRunOutputBox.ReadOnly = true;
            this.MovePDFsRunOutputBox.Size = new System.Drawing.Size(1511, 190);
            this.MovePDFsRunOutputBox.TabIndex = 7;
            this.MovePDFsRunOutputBox.Text = "";
            // 
            // MovesProgressBar
            // 
            this.MovesProgressBar.AccessibleDescription = "MovesProgressBar";
            this.MovesProgressBar.AccessibleName = "MovesProgressBar";
            this.MovesProgressBar.Location = new System.Drawing.Point(14, 687);
            this.MovesProgressBar.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
            this.MovesProgressBar.Name = "MovesProgressBar";
            this.MovesProgressBar.Size = new System.Drawing.Size(1512, 15);
            this.MovesProgressBar.TabIndex = 8;
            // 
            // SearchRunOutputBox
            // 
            this.SearchRunOutputBox.AccessibleDescription = "SearchRunOutputBox";
            this.SearchRunOutputBox.AccessibleName = "SearchRunOutputBox";
            this.SearchRunOutputBox.BackColor = System.Drawing.Color.WhiteSmoke;
            this.SearchRunOutputBox.CausesValidation = false;
            this.SearchRunOutputBox.ImeMode = System.Windows.Forms.ImeMode.NoControl;
            this.SearchRunOutputBox.Location = new System.Drawing.Point(14, 60);
            this.SearchRunOutputBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
            this.SearchRunOutputBox.Name = "SearchRunOutputBox";
            this.SearchRunOutputBox.ReadOnly = true;
            this.SearchRunOutputBox.Size = new System.Drawing.Size(1511, 190);
            this.SearchRunOutputBox.TabIndex = 4;
            this.SearchRunOutputBox.Text = "";
            // 
            // MainWindow
            // 
            this.AccessibleDescription = "MainWindow";
            this.AccessibleName = "MainWindow";
            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
            this.ClientSize = new System.Drawing.Size(1540, 726);
            this.Controls.Add(this.MovesProgressBar);
            this.Controls.Add(this.MovePDFsRunOutputBox);
            this.Controls.Add(this.MovePDFsButton);
            this.Controls.Add(CreateSubFoldersLabel);
            this.Controls.Add(this.SearchRunOutputBox);
            this.Controls.Add(this.SearchProgressBar);
            this.Controls.Add(this.SearchStartButton);
            this.Controls.Add(this.DirectoryPathInput);
            this.Controls.Add(DirectoryPathLabel);
            this.DoubleBuffered = true;
            this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
            this.Name = "MainWindow";
            this.Text = "Find and Move Password Protected PDF\'s";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.TextBox DirectoryPathInput;
        private System.Windows.Forms.Button SearchStartButton;
        private System.Windows.Forms.ProgressBar SearchProgressBar;
        private System.Windows.Forms.Button MovePDFsButton;
        private System.Windows.Forms.ProgressBar MovesProgressBar;
        private System.Windows.Forms.RichTextBox MovePDFsRunOutputBox;
        public System.Windows.Forms.RichTextBox SearchRunOutputBox;
    }
}

I am wondering if there is a way to make the text box a static item? Or should I bet using something else to display the log?

I've tried initiating a new text box inside the OutBoxUpdater(), which got rid of the error, but doesn't seem to do anything. Or it did something, but not what I wanted lol.

public static void OutputBoxUpdater(string message, Color color)
{
    RichTextBox SearchRunOutputBox = new();

    SearchRunOutputBox.SuspendLayout();
    SearchRunOutputBox.SelectionColor = color;
    SearchRunOutputBox.AppendText(message);
    SearchRunOutputBox.AppendText(Environment.NewLine);
    SearchRunOutputBox.ScrollToCaret();
    SearchRunOutputBox.ResumeLayout();
}

Edit:

As per the first comment from Steve, and sorry I didn't mention that I had tried this before, when I remove static from the method, it pushes the error down to where I am trying to call the method from.

using Spire.Pdf;
using System;
using System.Drawing;
using System.IO;

namespace Find_Move_PWP_PDF_s
{
    public class PDFOpenToCheck
    {
        /// <summary>
        /// Takes in a file path and attempts to open the file, throwing an error if it cannot, then saying it's password protected, and logging the filepath.
        /// Also checks that the file is not empty, and if it is, logs the filepath to a different log.
        /// </summary>
        /// <param name="filePath">Current file path from stack.</param>
        public void TryToOpenPDF(string filePath)
        {
            PdfDocument pdf = new();
            FileInfo fi = new(filePath);

            try
            {
                pdf.LoadFromFile(filePath);
                MainWindow.OutputBoxUpdater(filePath   " successfully opened!", Color.Black);
            }
            catch (Exception)
            {
                //Not empty and is a PDF
                if (fi.Length > 0 && filePath.EndsWith(".pdf"))
                {
                    MainWindow.OutputBoxUpdater(filePath   " is password protected!", Color.Red);
                    LogWriters.WritePWPPDFLog(filePath);
                }
                //Is an empty file
                else if (fi.Length <= 0)
                {
                    MainWindow.OutputBoxUpdater(filePath   " is an empty file!", Color.Blue);
                    LogWriters.WriteEmptyFileLog(filePath);
                }
                //Is not empty and is not a PDF
                else
                {
                    MainWindow.OutputBoxUpdater(filePath   " is not a PDF!", Color.Green);
                }
            }
        }
    }
 }

EDIT: To show where TryToOpenPDF() is being called from.

namespace Find_Move_PWP_PDF_s
{
    public static class TraverseDirectoryTree
    {
        /// <summary>
        /// Recursive method to iterate through the directory structure below the provided start point.
        /// In this application, will also perform PDF checking with Spire as it iterates (Line 74).
        /// Uses stack based iteration.
        /// </summary>
        /// <param name="root">Starting parent directory.</param>
        public static void TraverseTree(string root)
        {
            // Data structure to hold names of subfolders to be examined for files
            // "Stack<T>" works by "first in last out" and could take a long time to build the initial stack before iteration begins
            Stack<string> dirs = new();

            if (!System.IO.Directory.Exists(root))
            {
                ArgumentException argumentException = new();
                throw argumentException;
            }
            dirs.Push(root);

            while (dirs.Count > 0)
            {
                string currentDir = dirs.Pop();
                string[] subDirs;
                try
                {
                    subDirs = System.IO.Directory.GetDirectories(currentDir);
                }
                // "Unauthorized Access Exception" will be thrown if we do not have discovery permission on a folder or file. 
                catch (UnauthorizedAccessException e)
                {
                    System.Diagnostics.Trace.WriteLine(e.Message);
                    //Console.WriteLine(e.Message);
                    continue;
                }
                //"Directory Not Found Exception" will be thrown if currentDir has been deleted by another application or thread after our call to Directory
                catch (System.IO.DirectoryNotFoundException e)
                {
                    System.Diagnostics.Trace.WriteLine(e.Message);
                    //Console.WriteLine(e.Message);
                    continue;
                }

                string[]? files;
                try
                {
                    files = System.IO.Directory.GetFiles(currentDir);
                }

                catch (UnauthorizedAccessException e)
                {
                    System.Diagnostics.Trace.WriteLine(e.Message);
                    //Console.WriteLine(e.Message);
                    continue;
                }

                catch (System.IO.DirectoryNotFoundException e)
                {
                    System.Diagnostics.Trace.WriteLine(e.Message);
                    //Console.WriteLine(e.Message);
                    continue;
                }
                // Perform the required action on each file here
                foreach (string file in files)
                {
                    try
                    {
                        PDFOpenToCheck.TryToOpenPDF(file);
                    }
                    catch (System.IO.FileNotFoundException e)
                    {
                        // If file was deleted by a separate application or thread since the call to "TraverseTree()", then just continue.
                        System.Diagnostics.Trace.WriteLine(e.Message);
                        //Console.WriteLine(e.Message);
                        continue;
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Trace.WriteLine(e.Message);
                        //Console.WriteLine(e.Message);
                    }
                }

                // Push the subdirectories onto the stack for traversal
                foreach (string str in subDirs)
                    dirs.Push(str);
            }
        }
    }
}

CodePudding user response:

Change OutputBoxUpdater() so it is NOT static:

public void OutputBoxUpdater(string message, Color color)
{  
    SearchRunOutputBox.SuspendLayout();
    SearchRunOutputBox.SelectionColor = color;
    SearchRunOutputBox.AppendText(message);
    SearchRunOutputBox.AppendText(Environment.NewLine);
    SearchRunOutputBox.ScrollToCaret();
    SearchRunOutputBox.ResumeLayout();
}

Then change the signature of TryToOpenPDF() to receive MainForm as a parameter so you can use it:

public void TryToOpenPDF(string filePath, MainForm mf) {

    // ... code ...

    mf.OutputBoxUpdater(filePath   " successfully opened!", Color.Black);

    // ... code ...
}

Note that I'm using the parameter name mf, and not the name of the Form itself.

Somewhere in MainForm, you are presumably calling TryToOpenPDF() but you haven't shown that yet.

It'd look something like:

// ... within MainForm code ...

PDFOpenToCheck pdf = new PDFOpenToCheck();
pdf.TryToOpenPDF("some file path", this);

Note we are passing the current instance of MainForm, the one that is already visible, via this!

--- Edit ---

So you now you have to make a choice, pass the reference first to TraverseTree(), which then passes it on to TryToOpenPDF(), or CHEAT with:

MainForm mf = Application.OpenForms.Cast<MainForm>().Where(x => (x is MainForm)).FirstOrDefault();
if (mf != null)
{
    // ... do something with "mf" ...
}

Note that this assumes there will only ever be ONE instance of MainForm. This approach is generally frowned upon, though...

  • Related