I'm trying to learn, and have run into a little difficulty.

Trying to add a class to my program, passing a structure as the parameter to the class, and get "The best overload method match...has some invalid arguments" error message - and I just plain don't understand it!

// in program's MainWindow code:
    struct InData
    {
        public DateTime cDate;
        public string cName;
    }

    //---
    int ptr = 0;
    List<InData> CmtList = new List<InData>;
    InData prmList = new InData();

    //---
    // program code populates CmtList
    //---
    // when btnPrint is clicked
    prmList = CmtList[ptr];
    using (clsPrint cp = new clsPrint)
    { cp.PrintComments(prmList); }

// in clsPrint code:
    struct cmData
    {
        public DateTime cDate;
        public string cName;
    }
    //---
    public void PrintComments(cmData prmData)
    { ... }

I'd really appreciate it if someone could point me in the direction of what I'm doing wrong here.

Edited 3 Years Ago by GhostWolf

Something like this might be what you're looking for:

    struct InData
    {
        public DateTime cDate;
        public string cName;
    }
    public class clsPrint
    {
        InData cmData = new InData();
    }

What I currently have coded in the class module is:

namespace PrintStuff
{
    public class clsPrint : IDisposable
    {
        struct cmData
        {
            public DateTime cDate;
            public string cName;
        }

        cmData prtData;   // used for output in PrintCommentPage

        public void PrintComments(cmData prmData)
        {
            // System.Drawing.Printing initialization
            prtDoc.PrintPage += new PrintPageEventHandler(PrintCommentPage);
            prtData = prmData;
            prtDoc.Print();
        }

        private void PrintCommentPage(object sender, PrintPageEventArgs e)
        {
            // output the data
        }
    }
}

Maybe it's too late in the week, and obtuse has taken over, but I just don't understand what's different about InData in the MainWindow and cmData in the class. Aside from different names and locations, the structure of them both is exactly the same, (gotta love copy/paste!).

It sounds like you are defining the structure twice, which makes them different structures (even though they have the same internal data).

The main difference most likely is scope.  Making it public outside the class makes it more available to the rest of your project.

Please tell me if I've done this wrong, but the two definitions are by design:
- inData is the definition in the MainWindow, (WPF), module;
- cmData is its definition in the clsPrint class module.

Now that you mention it, I think one of the error messages said something about inData is more accessible than cmData. The structures themselves aren't scoped, so I guess the next thing I'll try is to remove the public scope from their fields.

PrintDoc Here's some code you might find useful. The first is a class for printing text to the default printer. The second is a way to output a string from a structure and send it to the printer using my PrintDoc class.

PrintDoc - Declare a new PrintDoc object passing the text to print as a string. You can also pass a name as string to put at the top of the page, the font you want to use, or change the orientation from landscape to portrait.

using System;
using System.Drawing;
using System.Drawing.Printing;
namespace PrintDocClass
{
    public class PrintDoc
    {
        private PrintDocument pd1 = new PrintDocument();
        private Font _pdfont = new Font("Microsoft Sans Serif", 8.25f);
        private string _PrintString = "";
        private string _Name = "";
        private bool _Landscape = false;
        public PrintDoc(string PrintString, bool Landscape = false)
        {
            _PrintString = PrintString;
            _Landscape = Landscape;
        }
        public PrintDoc(string PrintString, string DocName, bool Landscape = false)
        {
            _PrintString = PrintString;
            _Name = DocName;
            _Landscape = Landscape;
        }
        public PrintDoc(string PrintString, string DocName, Font PrintFont, bool Landscape = false)
        {
            _PrintString = PrintString;
            _Name = DocName;
            _pdfont = PrintFont;
            _Landscape = Landscape;
        }
        public void Print()
        {
            pd1.DefaultPageSettings.Landscape = _Landscape;
            pd1.PrintPage += new PrintPageEventHandler(pd1_PrintPage);
            if (_Name != "")
                _PrintString = _Name + "\n\n" + _PrintString;
            pd1.Print();
        }
        private void pd1_PrintPage(object sender, PrintPageEventArgs e)
        {
            int charactersOnPage = 0;
            int linesPerPage = 0;
            // Sets the value of charactersOnPage to the number of characters
            // of stringToPrint that will fit within the bounds of the page.
            e.Graphics.MeasureString(_PrintString, _pdfont,
            e.MarginBounds.Size, StringFormat.GenericTypographic,
            out charactersOnPage, out linesPerPage);
            // Draws the string within the bounds of the page
            e.Graphics.DrawString(_PrintString, _pdfont, Brushes.Black,
            e.MarginBounds, StringFormat.GenericTypographic);
            // Remove the portion of the string that has been printed.
            _PrintString = _PrintString.Substring(charactersOnPage);
            // Check to see if more pages are to be printed.
            e.HasMorePages = (_PrintString.Length > 0);
        }
    }
}

Format string from structure

    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            cmData prtdata = new cmData();
            prtdata.cDate = DateTime.Now;
            prtdata.cName = "MY Name";
            PrintDocClass.PrintDoc pd = new PrintDocClass.PrintDoc(prtdata.ToString());
            pd.Print();
        }
        struct cmData
        {
            public DateTime cDate;
            public string cName;
            public override string ToString()
            {
                return cName + " " + cDate.ToLongDateString();
            }
        }
    }

You can see how keeping the printing operation separate from the formatting of the text simplifies your code tremendously. Also how easy it is to output a formatted string from a structure bt overriding the ToString() method.

Edited 3 Years Ago by tinstaafl

Looks like I've got a lot to learn! Coming from a VB6 & AS/400 RPG background, it would seem to me that _PrintString = _PrintString.Substring(charactersOnPage); would truncate _PrintString to what's already been printed - leaving nothing more to print.

The actual structure has ~20 data fields in it, but I think I can build on the sample you've provided to get the job done.

This gives me two things to try when I get back to work Monday...

What the code does is remove what's been printed from the _printstring. The first parameter in Substring is the start index, so basically it's counting how many character have been printed up to a whole page, then takes the rest of the string, then as long as the string still has characters in it, leaving e.HasMorePages true will fire the event again until the _printstring is empty.

I'm glad this can be of some help. Let us know if you have any other difficulties. And as always if your question has been answered please remember to mark this solved. Thanks.

Edited 3 Years Ago by tinstaafl

This article has been dead for over six months. Start a new discussion instead.