How to communicate between different winforms - c#

I have a container WinForm called frmMain which holds another forms like frmOrder, frmMessage, the subforms was added in a TabPage control.
What I want to do is communicating between subforms, say user changes something in frmOrder and frmMessage need to be notified, currently I think the communication need to be delegated through the frmMain.
One solution I can think is to make subforms deriving from my custom Form derived class which defines interface say:
public class MessageEnabledForm: Form
{
public void SendMessage(String destFormName, String messageType, String data);
public void ReceiveMessage(String destFormName, String messageType, String data);
}
I don't know whether this is feasible, and is there any other solutions I can employ? which is generic and needn't to know the concrete subform.

Based on your question, I don't think inheritance is the best tool for the job. I say its not the best choice because you are not dealing with an "is a" relationship. I think you should consider using Events and Delegates to handle the communication between forms and subforms. The following MSDN article provides a good overview of Handling and Raising Events. You also may want to refresh yourself on the .NET INotifyPropertyChanged Interface if you using data binding in the subforms.

You could use an Interface like this, that all the child forms implement:
public interface Communication
{
public delegate void SendMessageDelegate(String destFormName, String messageType, String data);
public event SendMessageDelegate SendMessage;
public void ReceiveMessage(String destFormName, String messageType, String data);
}
When the main form receives the event, it can iterate over its "child" forms looking for a match on destFormName then call its ReceiveMessage() implementation (after casting it to the Communication interface).

Related

Extending a class with a new nested class

first question so I'm open to advice on effectively participating in the StackOverflow community as well as pertaining to the question.
I'm working on a text-based UI in C#. I have an abstract window class and an abstract control class, each of which implements common functionality for the types that inherit them (e.g. pop-up windows or text box controls). Currently, within a program that might implement the library, a developer would have to create window objects and control objects, and then add the controls to their respective windows, and the windows to a window manager class, like this:
var mainWindow = new MainWindow(...);
var textBox1 = new TextBox(...);
mainWindow.AddControl(textBox1);
WindowManager.Add(mainWindow);
This works, but it's a bit clunky. Since a control should never have to exist outside of a window, I was hoping to implement the control types as nested types. However, to maintain extensibility of the program, I'd like for there to be a way to extend the window class with new control types. My question is this: Should I use reflection, or rely on developers using container classes to extend the window class? Alternatively, is there a better way to structure the program than how it's currently laid out?
I've also considered using generics, e.g.:
public abstract class Window : DrawableObject, IWindow
{
public void AddControl <T>(object[] constructorArgs) where T : class, IControl
{
}
}
I'm aiming for ease of implementation without sacrificing extensibility/loose coupling. Thanks in advance for any thoughts!
EDIT: Should clarify, the primary reason for this is to fix some weirdness with how Windows and Controls cooperate. Each control has a parentWindow property which is used to access the window on which a control resides, for various purposes like creating an exit button for a particular window, etc.
Right now, this property is passed to the constructor, but that seems redundant to me since after doing so you have to add the control to the window's control list. I'd like to find a way to set this property when the control is added to a window instead, but restrict this action to when the control is added only, to prevent potential problems if the parentWindow property is changed outside of this context.
The way you coded AddControl method:
public void AddControl <T>(object[] constructorArgs)
where T : class, IControl
{
}
You intend developers to just provide type and your AddControl method will create an instance of it using constructorArgs. This method itself implicitly forces you to use reflection. Anything else does not stand a chance. Because To Add control of type T, Creating Instance of Control of type T is necessary. Since your Window class does not have a clue about T reflection is the only solution.
To facilitate other approaches, you might want to consider few overloads of AddControl.
public virtual T AddControl <T>()
where T : class, new(),IControl
{
//now you can create instance no reflection required
var control = new T();
this.Controls.Add(control);
return control;
}
public void AddControl <T>(T control)
where T : class, IControl
{
}
public abstract void AddControl <T>(object[] constructorArgs)
where T : class, IControl;
Creating an abstract method passes onus of implementation on child class and creating new instance of T can be handled the assuming type of T is known there or at-least all cases of known types of what T might be are handled.
It's a wide scope topic and I guess subjective as well. The best use of OOP is to achieve a design which fits your logical objective whatever that maybe.

Is it a bad idea to give a C# form a static property pointing to the only instance of the same form?

I have a fairly simple application that monitors folder activity and logs it on a server.
In this application I start off with a Form object called Form1. On this form I have a NotifyIcon. Because I need to change the text in the BalloonTip of the NotifyIcon from different Forms along the way, I was thinking of setting a static property of Form1 that will point to the only instance of Form1. This is how it would look in my oppinion:
public partial class Form1 : Form
{
private static Form1 staticRef;
// Other private properties
public Form1()
{
InitializeComponent();
staticRef = this;
// Rest of constructor logic
}
public static void changeNotifyBalloonText(String newText, int timeInMillis)
{
if (staticRef != null && staticRef.notifyIcon1 != null)
{
staticRef.notifyIcon1.BalloonTipText = newText;
staticRef.notifyIcon1.ShowBalloonTip(timeInMillis);
}
}
// Rest of public and private methods
}
Other things to be noted:
a. There will never be more than 1 instance of Form1.
b. I always check the value of staticRef against null, before trying to use it.
c. I cannot afford to make a temporary, local instance of Form1 just to set a BalloonTip message.
d. This solution works very well, i'm more interested in knowing if it's "too hacky" and if so - what would be a better approach to my issue?
e. The closest thing I've found that may answer my question (about static properties) to some degree is here:
Is using a static property in a form bad practice knowing that there's only only one instance of the form?
What you have here is a form of the singleton pattern.
The singleton pattern certainly has its detractors and its defenders (google "singleton anti-pattern").
It is though a very convenient way of doing this.
I would recommend an approach like either::
Create a class that represents operations on a notify icon.
Have that class as the only class that accesses staticRef.notifyIcon1.
Have it do so as a reference to notifyIcon1, not as Form1.
Have a static method or property that gets the icon-controlling class.
Or:
Simply have a static method or property that returns the NotifyIcon object.
Make it the only method that accesses the static reference to the form.
The advantage of one over the other is around whether you want to expose the full interface of NotifyIcon or provide a set of operations that make sense to your application.
This way you are still using the singleton pattern, but in restricting the way that it is accessed the fact that there is global state has less of a global impact, relates more directly to the purpose of that global state (the icon itself), and is more readily extended to different uses. e.g. if you some day need to have two icons, you change the method that static method or property to one that does a lookup of some sort, and change all the current calls to use the key for the first icon. Meanwhile, implementation changes up to and including completely changing which form provides that icon can be done quickly in one place.
I think your current design is tightly coupled to other classes sending the notification and it requires your form to be a single instance as well.
You can decouple this a great deal by using an event broker to send the notification to any interested parties. Many frameworks have event brokers, I have used one from Prism but there are others as well.
Your code will then only know about the event broker and what events your class is interested in.
public partial class Form1 : Form
{
private static IEventBroker eventBroker;
// Other private properties
public Form1(IEventBroker eventBroker)
{
InitializeComponent();
this.eventBroker = eventBroker;
this.eventBroker.Register<NotifyBaloonText>(changeNotifyBalloonText);
}
public static void changeNotifyBalloonText(NotifyBaloonText args)
{
notifyIcon1.BalloonTipText = args.NewText;
notifyIcon1.ShowBalloonTip(args.TimeInMillis);
}
// Rest of public and private methods
}

How to generate a Program template by generating an abstract class

i have the following problem.
The 1st step is to implement a program, which follows a specific protocol on startup.
Therefore, functions as onInit, onConfigRequest, etc. will be necessary.
(These are triggered e.g. by incoming message on a TCP Port)
My goal is to generate a class for example abstract one, which has abstract functions as onInit(), etc.
A programmer should just inherit from this base class and should merely override these abstract functions of the base class.
The rest as of the protocol e.g. should be simply handled in the background (using the code of the base class) and should not need to appear in the programmers code.
What is the correct design strategy for such tasks? and how do I deal with, that the static main method is not inheritable? What are the key-tags for this problem? (I have problem searching for a solution since I lack clear statements on this problem)
Goal is to create some sort of library/class, which - included in ones code - results in executables following the protocol.
EDIT (new explanation):
Okay let me try to explain more detailled:
In this case programs should be clients within a client server architecture.
We have a client server connection via TCP/IP. Each program needs to follow a specific protocol upon program start:
As soon as my program starts and gets connected to the server it will receive an Init Message (TcpClient), when this happens it should trigger the function onInit().
(Should this be implemented by an event system?) After onInit() a acknowledgement message should be sent to the server. Afterwards there are some other steps as e.g. a config message from the server which triggers an onConfig and so on. Let's concentrate on the onInit function.
The idea is, that onInit (and onConfig and so on) should be the only functions the programmer should edit while the overall protocol messaging is hidden for him.
Therefore, I thought using an abstract class with the abstract methods onInit(), onConfig() in it should be the right thing. The static Main class I would like to hide, since within it e.g. there will be some part which connects to the tcp port, which reacts on the Init Message and which will call the onInit function.
2 problems here:
1. the static main class cant be inherited, isn it?
2. I cannot call abstract functions from the main class in the abstract master class.
Let me give an Pseudo-example for my ideas:
public abstract class MasterClass
{
static void Main(string[] args){
1. open TCP connection
2. waiting for Init Message from server
3. onInit();
4. Send Acknowledgement, that Init Routine has ended successfully
5. waiting for Config message from server
6.....
}
public abstract void onInit();
public abstract void onConfig();
}
I hope you get the idea now!
The programmer should afterwards inherit from this masterclass and merely need to edit the functions onInit and so on.
Is this way possible? How?
What else do you recommend for solving this?
EDIT:
The strategy ideo provided below is a good one! Check out my comment on that.
Take a look at this, Strategy design pattern, it may help. A short code example below:
class MainClass {
static void Main(string[] args) {
// Where ProcessingStrategy is your abstract class.
// SpecificProcessingStrategy is someone else's implementation.
//
ProcessingStrategy strategy = new SpecificProcessingStrategy();
// Processor is implemented and provided by you and calls the appropriate methods on the
// ProcessingStrategy..
//
Processor processor = new Processor( strategy );
processor.Process();
}
}
If you wanted to provide the Main also, then take a look at having the name of the concrete ProcessingStrategy (SpecificProcessingStrategy in this example) passed in on the command line and load it dynamically (I'm not sure how to do this in C# but I'm sure many examples on the web).
What you are describing is the Template design pattern. Your abstract client contains the protocol details, and delegates to subclasses via protected template/hook methods to allow a conceret client to customize the behavior.
// In your provided library
public abstract class Client
{
public void Run()
{
OpenConnection();
WaitForInitMsg();
OnInit(); // notify subclass
SendInitAckMsg();
WaitForConfigMsg();
OnConfig(); // notify subclass
SendConfigAckMsg();
// etc, etc
}
protected abstract void OnInit() {}
protected abstract void OnConfig() {}
}
// customer/client uses the functionality like this
public class ConsoleClient : Client
{
protected void OnInit()
{
Console.WriteLine("Initialized");
}
protected void OnConfig()
{
Console.WriteLine("Configured");
}
}
public class MainClass
{
static void Main(string[] args)
{
ConsoleClient client = new ConsoleClient();
client.Run();
}
}
The customer never has access to any internals of your Clinet object that you don't explicitly expose.
Well, you are already made a good decision in choosinhg abstract class. Good in it is that you can define abstract methods which consumer (who inherited from it) must override, and have also "normal" methods with code in it. In this way you create a constrains for derived type to implement several set of the functions and plus, provide it with a common set of the functions that any derived type will have by default.

Passing values between three forms in C# .NET

I have a windows application which has three forms : Form1,2,3.
--Form 1, has two buttons , openform2, openform3.
--Form2 has a textbox form2_textbox,and button form2_button
--Form3 has a textbox form3_textbox
now, on clicking button openform2 on form1, Form2 opens, a string is entered in textbox form2_textbox of Form2, now when bu tton form2_button of this form is clicked, then i want that Form1 receives this string value & stores it in a string receivefromform2,
and then displays this string value on to form3_textbox of Form3.
please guide me how to do this task?
Ignore the fact that they're forms. Think of them as any other objects - you'd use properties, methods, events and constructors. GUI controls have a few oddities around them, mostly in terms of thread affinity, but usually you should apply the same object oriented approaches to them as you would anything else.
For example, when constructing Form2 in Form1, add an event handler to the button in Form2 (either by creating a new event in Form2 or exposing the button via a property and attaching it directly). The event handler would ask Form2 for the text in the textbox, and use that when creating Form3.
There are a couple of ways to do this. Using .NET events is one but requires pretty coupled wiring.
What I would suggest (and this is how I do this) is to use your own bus (observer pattern). Let's call it MessageBus. All your forms could use the same instance of this bus and when something interesting happens you could publish some Message. I would keep it strongly typed but for the sake of simplicity let's say this:
public class Message<T>
{
public string Name { get; set; }
public T Data { get; set; }
}
You would then have subscribers on your bus that respond to messages that they are interested in.
public class MessageBus
{
public void Subscriber(ISubscriber subsriber)
{
// register your subscriber in some list
}
public void Publish(Message message)
{
// loop through subscribers and let them know
// e.g. subscriber.Handle(message);
}
}
So to wire all this up each form that would like to publish an event (such as your form2) would need a reference to the message bus and each object that is interested in receiving events (such as form3) would register as a subscriber.
The only difference between this an using .NET events is that the various publishers and subscribers do not need to know about each other so they are loosely coupled --- they only need to know about the bus. It is possible to get the same loose coupling using .NET events but that takes a lot of fancy footwork.
More than one way to skin a cat I suppose.
I have a more mature implementation of this in my composite ui framework I use for the tooling on our FOSS service bus. You can take a look if you are interested:
Shuttle Service Bus on CodePlex
If you download the source you will find it in the Shuttle.Core.UI project.
Hope it makes sense.

Interactions between windows

what's the best/proper way of interacting between several windows in C# app?
Recently, I've run into a problem where one of program windows has to call method modifying main window. My solution was to create factory-like class, that would arrange all underlying model-data and organize the communication between various windows (through delegates). However, as passing one or two delegates was not a problem, I started thinking what if my other windows would need 10 delegates to interact properly with main window? Are delegates good solution? How to pass them in good way - through constructor, properties? Or maybe the need of using that many delegates is some serious design flaw itself?
You need to split the Model from the view by a Controller. Put an object that will be able to have both form reference and that will be able to manage the shared information.
An other solution is to send the reference of the formX to the formY this way they can communicate.
We use a custom built forms manager that uses the subject/observer pattern.
Every form that is opended is reported to the FormsManager, the FromsManager makes itself an observer of the form.
It also makes the form an observer of the FormsManager.
So you end up with every form observing the FormsManager and the FormsManager observing every form. Each form can then communicate to any other form via the FormsManager without each form having to be aware of all the others.
If it's only needing to interact with the main window, why not give a reference to the main window in the constructor of the others?
public class MainForm : Form
{
}
public class OtherForm : Form
{
protected MainForm MainForm { get; set; }
public OtherForm(MainForm mainForm) : base()
{
this.MainForm = mainForm;
}
}
EDIT:
Simple and effective.
If your forms need to interact with all the other forms of the application, then a service locator type pattern might be better suited.
Previously with MFC, there was something that notify all windows. You will pass an event id with a parameter.
You could do something similar with one delegate that will expose an event id and a collection of parameter.
The greatest advantage of this is that windows only have to implement one gateway.
You can use a single delegate, using a custom EventArgs to pass several informations, like: type of notificaton, additional parameters, etc.

Categories