How to access a form function from a different class - c#

public partial class Form1 : Form
{
public disp(string strVal)
{
lbl1.text = strVal;
}
private void button1_Click(object sender, EventArgs e)
{
class1 cl = new class1;
cl.Show1("test",this);
}
}
---------------- Class ------------
public class class1
{
private Form frm1;
public void Show1(string xName , object xfrmObj)
{
frm1 = (form) xfrmObj;
frm1.disp(xName ); // here I am getting error .
}
}
------------------------------------------/
here i am trying to access 'disp' function from class and i have pass 'form1' as a object , but i am getting error
The error message that I am getting is
Error 3
'System.Windows.Forms.Form' does not contain a definition for 'disp'
and no extension method 'disp' accepting a first argument of type 'System.Windows.Forms.Form' could be found
(are you missing a using directive or an assembly reference?)
this syntax in vb.net is working perfect.
please help me.....
Rajesh.

you need to cast frm1 = (Form1)xfrmObj; instead of casting it to form in your Show1(xName,xfrmObj) method.
EDIT: OP has stated in a comment that he needs this to work for several different forms.
You can make all your forms implement the same Interface, like so:
public partial class Form1 : Form, ICanDisplay
{
public void disp(string strVal)
{ //...
}
}
public partial class Form2 : Form, ICanDisplay
{
public void disp(string strVal)
{ //...
}
}
public interface ICanDisplay
{
void disp(string strVal);
}
then, change your method so it casts to ICanDisplay:
public class class1
{
private Form frm1;
public void Show1(string xName , object xfrmObj)
{
frm1 = (ICanDisplay) xfrmObj;
frm1.disp(xName);
}
}
However, as #Heinzi has noted, you should change your Show1-method to the following:
public void Show1(string xName, IDisplayForm xfrmObj)
{
xfrmObj.Disp(xName);
}
this will make the cast entirely unnecessary. The next step is to select meaningful names for your variables, functions and classes.

Related

Routine call in other namespace

I wanted to use a DLL library code and link / reference it with my c# code. The reference seems to be working, when defining var instance = new ProjectM1() without any problems.
But in the following line appears an error that ProjectM1 does not contain a definition for ProjectM1 and it couldn't find a extension method (Maybe a using directive or assembly reference is missing)
namespace GanttC
{
public class ProjectM1 : ProjectM1<Task, object>
{
}
public class ProjectM1<T, R> : IProjectM1<T, R>
where T : Task
where R : class
{
public ProjectM1() (routine to call !)
{
Now = 0;
Start = DateTime.Now;
TimeScale = GanttC.TimeScale.Day;
}
}
}
Here now the main code to call routine ProjectM1 in public class ProjectM1:
using GanttC
namespace WindowsApp2
{
public partial class Form4 : Form
{
Form2 fh;
public Form4(Form2 caller)
{
fh = caller;
InitializeComponent();
}
private void Form4_Load(object sender, EventArgs e)
{
var instance = new ProjectM1();
instance.ProjectM1(); (error !!!)
}
}
}

c# Calling an method from an object

So I roughly got this:
public partial class Form1 : Form
{
GameEngine engine;
public Form1()
{
engine = new GameEngine();
}
public void repaint()
{
}
}
class GameEngine
{
public void update()
{
}
}
Now i wanna add something to the update() method, which makes it call the repaint() method, inside of that instance of the Form1 class, in which the respective object of the GameEngine class was created.
In java i could've done it like this
engine = new GameEngine()
{
public void repaintCaller()
{
repaint();
}
};
and call repaintCaller() in the update() method, but that doesn't work in c#, now what is the equilvalent way to do this in c#?
One way to have it is:
public partial class Form1 : Form
{
GameEngine engine;
public Form1()
{
engine = new GameEngine();
engine.update(this);
}
public void repaint()
{
}
}
class GameEngine
{
public void update(Form1 form)
{
form.repaint();
}
}
You could pass to the GameEngine.update method an Action delegate to the repaint method in the form instance
public partial class Form1 : Form
{
GameEngine engine;
public Form1()
{
engine = new GameEngine();
// I put the call here for demo purpose,
// of course you call the engine.update
// method when you need and where you want
engine.update(repaint)
}
public void repaint()
{
Console.WriteLine("repaint called in the Form1 instance");
}
}
class GameEngine
{
public void update(Action clientUpdate)
{
if(clientUpdate != null)
clientUpdate.Invoke();
// or just... clientUpdate();
}
}
The parameterless Action delegate in C# is a way to pass, as parameter, a method (repaint) to the called method (update). Of course, you could pass the whole Form1 instance to the update but this approach binds the GameEngine class to the Form1 class. With the Action approach you are free from this coupling and you could pass any other method that returns void and doesn't take any parameter defined in any class of your program. This frees your GameEngine.update method from any specific bind to the caller.
I would try something like that
class GameEngine
{
public void update(ref Form1 caller)
{
caller.Refresh() //msdn says "Forces the control to invalidate its client area and immediately redraw itself and any child controls."
}
}
public partial class Form1 : Form
{
[...]
engine = new GameEngine()
engine.update(ref This)
}
I'm not sure of anything, i'm not used to C#.
I just hope it will help a bit :)
You can also set Events from your form, like this:
public partial class Form1 : Form
{
GameEngine engine;
public Form1()
{
InitializeComponent();
engine = new GameEngine();
engine.repaintRequired += engine_repaintRequired;
engine.update();
}
private void engine_repaintRequired(object sender, EventArgs e)
{
repaint();
}
public void repaint()
{
Console.Write("repaint");
}
}
class GameEngine
{
public event EventHandler repaintRequired;
public void update()
{
onRepaintRequired();
}
private void onRepaintRequired()
{
if (repaintRequired != null)
repaintRequired(this, new EventArgs());
}
}

How to pass a value to the list box to another class

I have to called a method Run in the Class1. And now I try to return str to listbox Running. I know this code Running.Items.Add(str); is not correct because it is in a different class. Please tell me how to fix it?
Class1.cs
class Class1
{
public void Run()
{
string str = "Hello";
Running.Items.Add(str);
}
}
Form1.cs
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Running_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
Update How do I call a class method
Form1
public void Invoke(string typeName, string methodName)
{
Type type = Type.GetType(typeName);
object instance = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod(methodName);
method.Invoke(instance, null);
}
private void Start_Click(object sender, EventArgs e)
{
new Task(() => { Invoke("Worker." + name, "Run"); }).Start();
}
You don't show how you call Run(), so I'm going to assume you do so from Form1.
You need to pass a reference one way or the other. Making your class Class1 dependent on your form is a bad idea. You can make it dependent on the lsitbox, and rename it accordingly:
public class ListBoxAdder()
{
private ListBox _listBox;
public ListBoxAdder(ListBox listBox)
{
_listBox = listBox;
}
public void Run()
{
string str = "Hello";
_listbox.Items.Add(str);
}
}
Then call it from your form and pass the reference to the Running ListBox:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var listBoxAdder = new ListBoxAdder(this.Running);
listBoxAdder.Run();
}
}
If you want to add the str object to the Running list in the class class1 you should just get a reference to the active form of the Form1 :
public void Run()
{
string str = "Hello";
((Form1)Form1.ActiveForm).Running.Items.Add(str);
}

Calling functions between different classes

I am used to writing embedded c and poorly skilled in c#.
My problem is that I want to be able to run the function openAnotherForm() from Welcome_Form and right now the code does not work. I patiently tried different things but only managed to push my frustration.
I simplified my relevant code to illustrate the problem.
File 1 - This will run and open file 2.
class UIcode
{
private Welcome_Form Welcome;
private AnotherForm_Form AnotherForm;
public UIcode()
{
Welcome = new Welcome_Form();
Application.Run(Welcome);
}
public void openAnotherForm()
{
Welcome.Hide();
AnotherForm = new AnotherForm_Form();
AnotherForm.ShowDialog();
}
}
File 2 - When I click TheButton, the program should run the function openAnotherFrom from file 1.
public partial class Welcome_Form : Form
{
public Welcome_Form()
{
InitializeComponent();
}
private void TheButton_Click(object sender, EventArgs e)
{
// Function from file 1
UIcode.openAnotherForm();
}
}
I realize the problem might be quite trivial but I would still be grateful for an explanation on how to do this.
Preferable: The functions from UIcode should only be recognized by classes specified by UIcode.
You can change the constructor to take a reference to the instance of UIcode that opened it:
private static UIcode myParent;
public Welcome_Form(UIcode parent)
{
myParent = parent;
InitializeComponent();
}
Now in UIcode:
public UIcode()
{
Welcome = new Welcome_Form(this);
Application.Run(Welcome);
}
And finally, back in Welcome_Form:
private void TheButton_Click(object sender, EventArgs e)
{
// Function from file 1
myParent.openAnotherForm();
}
Your openAnotherForm() method is not static, so it needs an instance reference in order to be used. Either instantiate a UICode object, or mark the method as static.
You to create an instance of the class in File1 to call the method. You've called the class UICode, so the constructor should be renamed from public UserInterface() to public UICode().
class UIcode
{
private Welcome_Form Welcome;
private AnotherForm_Form AnotherForm;
public UIcode() // Renamed Constructor
{
Welcome = new Welcome_Form();
Application.Run(Welcome);
}
public void openAnotherForm()
{
Welcome.Hide();
AnotherForm = new AnotherForm_Form();
AnotherForm.ShowDialog();
}
}
public partial class Welcome_Form : Form
{
public Welcome_Form()
{
InitializeComponent();
}
private void TheButton_Click(object sender, EventArgs e)
{
// Create an instance UICode
UICode instance = new UICode();
// Call the method from the instance, not from the class.
instance.openAnotherForm();
}
}
Alternatively, you can make openAnotherForm() a static method, but you'll also need to make the instance variables (Welcome and AnotherForm) static. You will also need to initialize them, but you can do that by making the constructor static as well.
class UIcode
{
private static Welcome_Form Welcome;
private static AnotherForm_Form AnotherForm;
public static UIcode() // Renamed Constructor
{
Welcome = new Welcome_Form();
Application.Run(Welcome);
}
public static void openAnotherForm()
{
Welcome.Hide();
AnotherForm = new AnotherForm_Form();
AnotherForm.ShowDialog();
}
}

object oriented: is it possible use a static instance like a variable?

I think I couldnt do this thing, but I try to ask (maybe :)).
Suppose I have this Main class :
public class UiUtils
{
public static MyObject myObject;
public UiUtils()
{
myObject=new MyObject();
}
}
now if I want to try to call this instance from another Context Class (web application), I do this :
public partial class context_eventi_CustomClass : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(UiUtils.myObject.Title());
}
}
but what I'd like to do is this :
public partial class context_eventi_CustomClass : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(myObject.Title());
}
}
so, use directly myObject and not UiUtils.myObject :)
I think this is not possible, but maybe I wrong and there are any strategies :) Thanks
** EDIT **
my solution for the moment :
public class UiUtils
{
public static MyObject myObject;
public UiUtils()
{
myObject=new MyObject();
iContext.myObject = myObject;
}
}
public class iContext : System.Web.UI.UserControl
{
public static MyObject myObject;
public iContext()
{
}
public iContext(MyObject myObject)
{
myObject = myObject;
}
}
public partial class context_eventi_CustomClass : iContext
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(myObject.Title());
}
}
seems to works! What do you think about?
Per MSDN,
A static method, field, property, or
event is callable on a class even when
no instance of the class has been
created. If any instances of the class
are created, they cannot be used to
access the static member. Only one
copy of static fields and events
exists, and static methods and
properties can only access static
fields and static events. Static
members are often used to represent
data or calculations that do not
change in response to object state.
and
"To access a static class member, use the name of the class instead of a variable name to specify the location of the member."
and
The static member is always accessed
by the class name, not the
instance name
#Daniel Earwicker says in his answer on SO here:
...Static members fail to integrate
well with inheritance. It makes no
sense to have them heritable. So I
keep static things in separate static
classes...
So I am not clear on your design why MyObject needs to be static. All you are trying to save is a little typing, but inheritance will not help you here either.
Edit:
I tried to replicate your code in a simple console application. The output is not what you would expect:
namespace ConsoleApplication1
{
public class UiUtils
{
public static int myObject = 1;
public UiUtils()
{
myObject = new int();
iContext.myObject = myObject;
Console.WriteLine("This is UiUtils\n");
}
}
public class iContext
{
public static int myObject = 2;
public iContext()
{
Console.WriteLine("This is iContext\n");
}
public iContext(int myObject)
{
myObject = myObject;
}
}
public class iContext2 : iContext
{
public static int myObject = 3;
public iContext2()
{
Console.WriteLine(myObject.ToString() + "\nThis is iContext2\n");
Console.WriteLine(iContext.myObject.ToString());
}
}
class Program
{
static void Main(string[] args)
{
iContext2 icontext = new iContext2();
Console.In.ReadLine();
}
}
}
The output ends up being this:
This is iContext
3
This is iContext2
If you add a call to iContext.myObject, then it outputs it's number:
This is iContext
3
This is iContext2
2
To access the object without typing the class you can use inheritance.
public class CustomClass : UiUtils
This will share UiUtils properties with CustomClass

Categories