Giving object in dll a click method from another project - c#

is it possible to adding a click method to a class in dll from another project?
I want to create a class (Class1) in a class library and build a dll from it.
I will use that class in a project with references the dll.
This is my class (Class1)
public class Class1
{
public ImageMap map = null;
public Class1(Form f)
{
map = new ImageMap();
map.RegionClick += f.RegionMap_Clicked;
}
}
and this is my form (Form1) in another project.
public partial class Form1 : Form
{
Class1 c = null;
public Form1()
{
InitializeComponent();
c = new Class1(this);
}
void RegionMap_Clicked(int index, string key)
{
MessageBox.Show(key);
}
}
This is my first time asking here. So, sorry if my english is bad.

Class1 can be made independent from Form1:
public class Class1
{
public ImageMap Map = null;
public Class1()
{
this.Map = new ImageMap();
}
}
And Form1 uses Class1 however it likes:
public partial class Form1 : Form
{
private Class1 c = null;
public Form1()
{
InitializeComponent();
this.c = new Class1();
this.c.Map.RegionClick += this.RegionMap_Clicked;
}
private void RegionMap_Clicked(int index, string key)
{
MessageBox.Show(key);
}
}
Thus only the Form1 project needs a reference to the Class1 project.

Yes it's possible, don't forget to make your handler public:
public void RegionMap_Clicked(int index, string key)
{
MessageBox.Show(key);
}

You should do this
public class Class1
{
public ImageMap map = null;
public Class1(Form1 f)
{
map = new ImageMap();
map.RegionClick += f.RegionMap_Clicked;
}
}
then
public partial class Form1 : Form
{
Class1 c = null;
public Form1()
{
InitializeComponent();
c = new Class1(this);
}
public void RegionMap_Clicked(int index, string key)
{
MessageBox.Show(key);
}
}
and of couse you shold add using for this assembly.
I think now it will be working well

Related

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());
}
}

Calling "Form" class method from "A" class without adding a reference to the "Form" class

I have two Projects one is a Winform application another is a Class library. I have added a reference to the class Library in Winform and called a method of the class library. Now I want to call a different method in winform application from class library but I can't add a reference to winform to the class library.
IN CODE:-
public partial class Form1 : Form
{
private void btn_Click(object sender, EventArgs e)
{
A obj = new A();
obj.foo();
}
public string Test(par)
{
//to_stuff
}
}
and in Class library
class A
{
public void foo()
{
//Do_stuff
//...
Test(Par);
//Do...
}
}
You can achieve this by injecting Test into class A.
For example:
public partial class Form1 : Form
{
private void btn_Click(object sender, EventArgs e)
{
A obj = new A();
obj.foo(Test);
}
public string Test(string par)
{
//to_stuff
}
}
class A
{
public void foo(Func<string, string> callback)
//Do_stuff
//...
if (callback != null)
{
callback(Par);
}
//Do...
}
}
While the callback method from David is a sufficient solution, if your interactions gets more complex, I would use this approach
Create an inteface in your class libary
public interface ITester
{
string Test(string value);
}
Rewrite your code so class A expects an ITester interface
public class A
{
public A(ITester tester)
{
this.tester = tester;
}
public string foo(string value)
{
return this.tester.Test(value);
}
}
Implement your interface in Form1
public partial class Form1 : Form, ITester
{
private void btn_Click(object sender, EventArgs e)
{
A obj = new A(this);
obj.foo("test");
}
public string Test(string value)
{
//to_stuff
return value;
}
}

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);
}

Can I inherit from an instantiated class?

I'm trying to inherit from an instantiated class. Why is the value of Inherited, in the code below, a null value? Is there a way to do this correctly?
namespace Sample {
public class Class1 {
static void Main() {
Class2 SecondClass = new Class2();
SecondClass.StartSomething("hello world");
}
}
public class Class2 {
public string Inherited;
public void StartSomething(string value) {
Inherited = value;
InheritSomething();
}
public void InheritSomething() {
Class3 ThirdClass = new Class3();
ThirdClass.DoSomething();
}
}
public class Class3 : Class2 {
public void DoSomething() {
Console.WriteLine(Inherited);//when complied Inherited is null
Console.ReadLine();
}
}
}
Inheriting occurs at compile time. (Therefore 'Inherited' does not have a value yet)
Values are assigned at run-time.
Inheriting from a class does not inherit the INSTANCE of that class at instantiation of the inherited class. Instead, you'd need to pass along the instance of that class. One option is to inject it into the constructor of class 3
public class Class1
{
static void Main()
{
Class2 SecondClass = new Class2();
SecondClass.StartSomething("hello world");
}
}
public class Class2
{
public string Inherited;
public void StartSomething(string value)
{
Inherited = value;
InheritSomething();
}
public void InheritSomething()
{
Class3 thirdClass = new Class3(this);
thirdClass.DoSomething();
}
}
public class Class3 : Class2
{
private Class2 _class2;
public Class3(Class2 class2)
{
_class2 = class2;
}
public void DoSomething()
{
Console.WriteLine(_class2.Inherited);
Console.ReadLine();
}
}

Using a delegate to populate a listbox

Ive been playing around with delegates trying to learn and I ran into one small problem Im hoping you can help me with.
class myClass
{
OtherClass otherClass = new OtherClass(); // Needs Parameter
otherClass.SendSomeText(myString);
}
class OtherClass
{
public delegate void TextToBox(string s);
TextToBox textToBox;
public OtherClass(TextToBox ttb) // ***Problem***
{
textToBox = ttb;
}
public void SendSomeText(string foo)
{
textToBox(foo);
}
}
the form:
public partial class MainForm : Form
{
OtherClass otherClass;
public MainForm()
{
InitializeComponent();
otherClass = new OtherClass(this.TextToBox);
}
public void TextToBox(string aString)
{
listBox1.Items.Add(aString);
}
}
Obviously this doesnt compile because the OtherClass constructor is looking for TextToBox as a parameter. How would you recommend getting around the issue so I can get an object from myClass into the textbox in the form?
You can change the OtherClass to something like
class OtherClass
{
public delegate void TextToBox(string s);
TextToBox textToBox;
public OtherClass()
{
}
public OtherClass(TextToBox ttb) // ***Problem***
{
textToBox = ttb;
}
public void SendSomeText(string foo)
{
if (textToBox != null)
textToBox(foo);
}
}
But I am not quite sure what you wish to achive with
class myClass
{
OtherClass otherClass = new OtherClass(); // Needs Parameter
otherClass.SendSomeText(myString);
}

Categories