DonationCoder.com forum
 
Read-only archive. This is a static copy of the DonationCoder.com forum. Reading and searching work as before; logging in, posting and private messages do not.
Archive of 2026-10-21 · About this archive · Main site

Author Topic: Forms calls a class, class interacting with a form  (Read 8,134 times)

mediaguycouk

  • Supporting Member
  • Joined in 2007
  • **
  • Posts: 247
Forms calls a class, class interacting with a form
« on: November 21, 2008, 07:21 PM »
If I have a textbox in a form called 'textbox' and a class called 'class' is there any way of doing this?

Form1:
textbox.text = "";
Class class = new Class();
class.runfunction()

Class:
public void runfunction()
{
form1.textbox.text = "Some text"; // This would never work, but how could it?
}
Learning C# - Graham Robinson

rht341

  • Participant
  • Joined in 2007
  • *
  • Posts: 8
Re: Forms calls a class, class interacting with a form
« Reply #1 on: November 21, 2008, 07:47 PM »
Hello,

There is more than one way to do this; one is to have the runfunction method take a TextBox as a parameter:

Form1:
textbox.text = "";
Class class = new Class();
class.runfunction(textbox)

Class:
public void runfunction(TextBox tx)
{
tx.text = "Some text"; // This would never work, but how could it?
}

mediaguycouk

  • Supporting Member
  • Joined in 2007
  • **
  • Posts: 247
Re: Forms calls a class, class interacting with a form
« Reply #2 on: November 22, 2008, 05:09 PM »
I never knew that, thanks.

Is it possible to do it in the class itself (so it is usable by all functions?)

Something like Class class = new Class(textbox);
Learning C# - Graham Robinson

rht341

  • Participant
  • Joined in 2007
  • *
  • Posts: 8
Re: Forms calls a class, class interacting with a form
« Reply #3 on: November 22, 2008, 06:43 PM »
Yes, you have to declare a special constructor (New) and have a private variable in the class:

Public Class MyClass
    private _tx as TextBox

    Public Sub New(ByVal txtBox as TextBox)
        _tx = txtBox
    End Sub

    Public Sub MyFunction(ByVal someText as String)
        _tx.Text = someText
    End Sub
End Class

CWuestefeld

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 1,009
    • Participated in NANY Challenge Once
Re: Forms calls a class, class interacting with a form
« Reply #4 on: November 22, 2008, 06:49 PM »
rht341 is certainly correct, but a couple of warnings:

1: In your proposal to put the reference to the textbox into your class's constructor, you've tied the life of the textbox to the life of your object. A reference to the textbox will keep it around as long as your class, and this may manifest itself as a memory leak, causing your program to die after having been active for some time.

2: In the 15-20 years that OO development has been popular, we've learned some lessons. Depending on the nature of your class, you may be about to step into one of the classic blunders. The most famous is never get involved in a land war in Asia, but only slightly less well-known is this: keep your application's data separate from its user interface. When things start to get bound together tightly, it becomes difficult to maintain your program as you need to make changes to either the UI or the data. Better to keep them separate, with a well-defined interface dictating how they interact. Probably the leading design for ensuring this is the Model-View-Controller pattern.

This same kind of question comes up in many areas, and developers have found many ways that work well for attacking them. These have been documented and gathered together in catalogs of "patterns" (e.g. here: http://www.dofactory.com/Patterns/Patterns.aspx ). You'll give yourself a big leg up if you read up on these. You'll get the benefit of many years of experience from developers that have gone before us.


f0dder

  • [Well, THAT escalated quickly!]
  • Charter Honorary Member
  • Joined in 2005
  • ***
  • Posts: 9,153
    • Participated in NANY Challenge Once
Re: Forms calls a class, class interacting with a form
« Reply #5 on: November 22, 2008, 06:58 PM »
CW: you don't get a leak from #1 unless you have a really unusual GUI design :)

Amen to #2, though. MVC 4tw.
- carpe noctem

CWuestefeld

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 1,009
    • Participated in NANY Challenge Once
Re: Forms calls a class, class interacting with a form
« Reply #6 on: November 22, 2008, 08:09 PM »
CW: you don't get a leak from #1 unless you have a really unusual GUI design :)

In .Net WinForms (which I assume is the environment, judging by the VB syntax), you will have a leak. This must be the case in any garbage-collected environment. In this example, the TextBox (and hence any handles it's using, too) cannot be collected while there are any live objects referencing them. The reference from MyClass will hold any referenced TextBox in memory until the MyClass object itself is collected.

I meant to offer a more concrete suggestion as a worthwhile and instructive step before jumping into MVC.

Declare an Event in your Class, and let your form listen for that event. This is easy to do: syntactically it's just like when your form waits for a button click or something like that. The advantage is that MyClass doesn't need to have the faintest idea of how the UI works. He just needs to shout out by way of the Event: "Hey! I've got a new value for myname (or whatever)!".

The same caveats about leaks apply, though. When you subscribe to the Event, you're holding a reference to the MyClass instance. That instance can't be garbage collected until the reference is cleared, either explicitly or by the death of the form that's listening to it.


mediaguycouk

  • Supporting Member
  • Joined in 2007
  • **
  • Posts: 247
Re: Forms calls a class, class interacting with a form
« Reply #7 on: November 22, 2008, 08:19 PM »
Something that I have learnt, which I havn't followed here, is that I shouldn't ask direct questions. I should say what I'm doing and ask for general advise.

Here is what I'm doing...

I have a front end interface for ffmpeg. Ffmpeg is a command line video encoding. The class in this case is Ffmpeg.cs, which runs all the arguements

Code: (csharp)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace H264Convert
{
    class Ffmpeg
    {
        // Where FFMPEG should be
        // This is also in Form1.cs
        public string ffmpegLocation = @"C:\program files\ffmpeg\ffmpeg.exe";

        // Create a new process
        System.Diagnostics.Process proc = new System.Diagnostics.Process();

        // Function to actually envoke FFMPEG
        public void runFFMPEG(string inputFile, string outputFile, string aspectRatio,
            string dimensions, string bitRate, string passes, string videoTypeArg,
            string audioFrequency, string audioBitRate, string deinterlace, string otherArgs, string audioCodec)
        {
            // See if the video to be output already exists
            if (File.Exists(outputFile))
            {
                
                // and stop FFMPEG from starting
                return;
            }
            // Create arguements from passed variables
            string arguement = " -i \"" + inputFile + "\"" +
                " -aspect " + aspectRatio +
                " -pass " + passes +
                " " + videoTypeArg +
                " -b " + bitRate +
                " -ar " + audioFrequency +
                " -ab " + audioBitRate +
                " -acodec " + audioCodec + 
                " -s " + dimensions +
                " " + deinterlace +
                " " + otherArgs +
                " " + "-y" + // Overwrite
                " \"" + outputFile + "\"";

            // Stop proc raising events
            proc.EnableRaisingEvents = false;
            // Location of file to start (FFMPEG)
            proc.StartInfo.FileName = ffmpegLocation;
            // Arguements to pass to file
            proc.StartInfo.Arguments = arguement;
            // Use shell execute
            proc.StartInfo.UseShellExecute = false;
            // Don't show FFMPEG
            proc.StartInfo.CreateNoWindow = false;
            // Do not steal information from the FFMPEG window 
            proc.StartInfo.RedirectStandardOutput = false;
            proc.StartInfo.RedirectStandardInput = false;
            proc.StartInfo.RedirectStandardError = false;
            // Start FFMPEG
            proc.Start();
            // Change processor priority from 'Normal' to 'Below Normal'
            proc.PriorityClass = System.Diagnostics.ProcessPriorityClass.BelowNormal;
            // Don't do anything else until it is done
            proc.WaitForExit();
            // Once FFMPEG is finished it will close. Just be sure that it is
            proc.Close();
            // Exit out of function
            return;
        }
    }
}

What I want is for the program to read the output from Ffmpeg.exe...

Code: (csharp)
            StreamReader sr = proc.StandardError;
          
            while ((s = sr.ReadLine()) != null)
            {
                t += s;
            }

            doSomethingWith(t);

... and update a progress bar and text box based on what the streamreader reads.

So I thought I needed to pass the text box, but is there a better way?
Learning C# - Graham Robinson

Original address: https://www.donationcoder.com/forum/index.php?topic=15834.0