Global function repository - c#

I have several Control such as ToolStripMenuItem and Button that need to have a function bound to their click event. They will either generate a new Form or add a TabPage to a current TabControl. I may end up having several different Control that will need the same function, so I thought of making a Global function repository.
I would have a class named Services looking like this:
public class Services {
TabControl container;
delegate void fonction(int id);
Dictionary<string, fonction> functions = new Dictionary<string, fonction>();
public Services(TabControl control) {
container = control;
InitFunctions();
}
public Delegate Getfunction(string name) {
if (functions.ContainsKey(name))
return functions[name];
else
throw new NotImplementedException("Failed to instantiate " + name );
}
// List of all the desired functions
// Function example
private void ProductLoan(int id) {
string name = "Loan"+id.ToString();
Form newForm = new Loan();
newForm.Text = Properties.Resources.MakeLoan;
newForm.ShowDialog();
}
private void InitFunctions() {
fonction f = new fonction(ProductLoan);
functions.Add("Loan", f);
// For each functions
// f = new fonction(name);
// functions.Add(name, f);
}
}
This class would be instantiated when the program start and stored globally so it can be accessed everywhere. Correct me if I am wrong to proceed like this, but I didn't make the Services class static since it needs to have an instance of the TabControl and to initialise the function list.
I have no clue if this is a good idea so I would appreciate some advice.

What programming environment are you using? I know that in Visual Studio, if you have several controls using the same method you can make the method under one of the click events and then, for each control that requires the same method, you can bind that method by having the controls actually bind to the click event of the first control you added that method to. As far as creating a repository that contains each function necessary, I have always had better luck just making the individual click events, I would suggest just making a class to hold the functions and making it static. Because Services needs something else instantiated first, just instantiate the TabControl then the static class holding your methods.

You could create something like TabController and PopupController with public instance methods for creating tabs and forms respectively. The TabController will probably have a dependency on TabControl and the PopupContorller will have a dependency on parent form (if needed). Every Control will have it's own event handler where the method from TabController and PopupController will be called.
UPD:
Since the Controls are created dynamically, a common facility for wiring the event handlers may be a good idea. But the wiring logic should be separated from event handler implementation logic to make it more readable and maintainable. For example IntelligentEventHandlerWiringManager could have a dependencies for TabController and PopupController.

Related

Execute a method from all instances of a class

I am designing a base class for TextForms and derived classes for Labels , Fields, Dialogboxes... etc.
i am using the below code
public class TextForm
{
public void Refresh()
{
}
}
public class Label : TextForms
{
public void Refresh()
{
}
}
and in my program i am instanciating many Labels .. and somewhere i need to call TextForms.Refresh() which must execute all derived classes instances Refresh() method .
i can't imagine how to do?
You can't find all the instances by default. Though, there are a few design patterns that will make it easier for you to do so. There is the Composite Design Pattern Which gives you the ability to add sub components to your components. For example, a Form/Window component will be a container of sub components like Labels and TextFields for example. Then, when you will call Refresh on the container (Form/Window - for example) it can call the Refresh on all of it's sub components.
There is also the Observable Design Pattern which let components register for 'events' (not necessarily implemented via .Net's Events). Then when you call the Refresh method on the observer, it will call the Refresh methods of all the observable's that are registered.
In your question, you write TextForms so I am assuming that this is an object that is an enumerable of some sort.
Liskows substitution principle dictates that if you have a base class of any kind you can always substitute derived classes for the base class
var textForms = new List<TextForm>();
textForms.Add(new Label());
textForms.Add(new TextBox());
so now you can simply iterate through this list as such:
foreach(var textForm in textForms){
((TextForm) textForm).Refresh();
}
You may have to tweak the example a little to get it working, but that is the general answer to your question.
Like m102 said it is unpractical if not impossible to find all instances. However, assuming you use a canvas or page to display your labels on, it is possible to get all the labels in that canvas.
TextForm tf = new TextForm();
foreach (Control ctrl in yourCanvas.Children.OfType<Label>())
{
tf.Refresh();
}
This will retrieve all the controls of type label from the canvas. This will not refresh them all at once.
Note: I do not recommend changing labels that are not visible/onscreen. It would require them to be kept in memory and this is performancewise not advised. Oh and your refresh function has a capital R (This is usually reserved for classes).

Best practice for having a class partnered with UserControl

I'm creating a set of classes called *Activity which all inherit from the interface IActivity e.g.
public interface IActivity
{
void StartActivity();
}
public class MyFirstActivity : IActivity
{
public int SomeVariable {get; set;}
public MyFirstActivity(int someVariable)
{
SomeVariable = someVariable
}
public void StartActivity()
{
//some code to do stuff with SomeVariable
}
}
This is so I can create an list/array of IActivitys and run their StartActivity() methods.
Now what I want to do is to have a UserControl (for editing any variables graphically and ordering activites graphically) for each class which inherits from IActivity.
What is the best way to do this?
My thoughts are either:
Create a separate UserControl for each Activity and then create an instance of the activity in the UserControl's constructor... or...
Make each activity a UserControl which inherits from IActivity. The issue is with this is that I may want to not use the UserControl elements in other parts of the program, just using the actions that each performs and using a UserControl for this will surely use more resources when it's not needed...
Any thoughts?
Edit:
The idea is that each Activity has some properties which can be edited and each performs a distinct action which is performed when it's StartActivity is called.
Activities can either be performed in code via creating instances of activities and adding to a list. Loop through the list to perform each StartActivity in order.
Alternatively on a Form, UserControls of each activity can created and dragged round the form into the desired order by the user (which behind the scenes populates the list) and then clicks a Start button (which loops round the list calling each StartActivity in turn.
This would be using WinForms.
You should go with your 1st thought. Take the *Activity as a Property(read-only) of the specific *UserContorl, and instantiate it through the UC constructor. Then You can set the Properties of the Activity visually through the UC.

Writing in a textbox in a form from another class

I need to write the result of my query in a textbox in the main form, from another class. What is the best and easy way to achieve this?
Your external class should not know anything about a textbox. It may know about your form in order to send the result there, but the elements are belong to the form and should not be exposed (it is what is called encapsulation).
I suggest you to have a meaningful method on your form, something like ShowListOfUsers(users), or whatever you do, call it appropriately so it can be understood externally.
Then in this method you put the result into the controls (textbox) as you want it.
I also suggest you to have an interface for the form which will contain such behavioral methods and have your window implemented this interface, something like:
public interface IOrderView
{
void ShowOrderDiscount(result);
}
so your external class will know only about the interface, not about the window, the textbox, etc.
Now your query component is trivial:
public class SomeOperation
{
private readonly IOrderView _view;
public SomeOperation(IOrderView view)
{
_view = view;
}
public void DoSomething(parameters)
{
var result = GetMyComplicatedResult();
_view.ShowResult(result);
}
}
The code above is not ideal (as I don't know what is your scenario), but the idea is there.
Good Luck.
Use a public property (or a getter) in your class to retrieve the output of the query.

MVVM: How to design a window hosting different applications?

I am trying to implement a simple WPF data analysis application using the MVVM design pattern, in which one can use several different methods to analyse some data (loaded from files).
In the first screen, the user should be able to choose the method he likes to employ. After he has done that, and loaded the data, the area previously occupied by the method selection screen should be replaced by the analysis results.
Currently, my MainWindowViewModel has a property "CurrentViewModel" of type object, that can be set to either the method selection viewmodel or on of the analysis results viewmodels, which are then rendered by using datatemplates.
The problem I am facing is, that I don't know how the different viewmodels should communicate.
The method selection screen needs a
list of available methods.
The main screen needs to know what method was
selected and choose the approriate
viewmodel to display the results.
The data loaded somehow needs to get into the class doing the actual work, and the results viewmodel needs to know about this to know where to get its data from.
Everything I can think of leaves the MainWindowViewModel to do all the negotiating between the different viewmodel and model classes.
How would I optimally design this?
For what it's worth, I helped implement a module for a similar Composite Application. So what follows is based on anecdotal experience,
To your first point, our application or "shell" needs an explicit enumeration of "available" methods. We can supply this any way we wish, either explicitly (via config) or implicitly (via reflection). As a preference, I favor the former as it is less "magical".
To your second point, in addition to an explicit enumeration our shell must maintain a map from choice to implementation. Again, this may be accomplished any number of ways, but typically our enumeration is a list of "Types", and when a type is selected we request an implementation of that type from a factory. The easiest way to implement this pattern is to leverage an Inversion of Control container, such as Castle Windsor, Unity, Ninject, etc. To be honest, I don't remember what we used internally.
For example, consider,
// a simple Plain Old C Object that describes business methods.
public class BusinessMethod
{
// user-friendly name
public string Name { get; set; }
// type that actually implements
public Type ImplementationType { get; set; }
}
// ... meanwhile, back on the ranch ...
public void OnBusinessMethodSelection ()
{
// 1. if selected
if (BusinessMethodList.SelectedItem != null)
{
// 2. retrieve selected item
BusinessMethod selected =
(BusinessMethod)(BusinessMethodList.SelectedItem);
// 3. request implementation of selected item from
// IoC container
object implementation =
_container.Resolve (selected.ImplementationType);
}
}
To your third point, we need a way for disparate parts to communicate. Unfortunately we cannot rely on design-time methods (ie Command and Data bindings), so we must implement our own Event Aggregation service. Basically a "singleton" (as in single instance not static class) that knows about subscribers and publishers, and preferably an implementation that offers strong typing of arguments. Fortunately for us, many a greater man have gone before us, and we may benefit from their experience. Check out Kent Boogaart's Event Hub.
Here is an example of how we would use an Event Aggregator
// an example of a strongly typed subject. notice how subject
// defines content. semanticly, when someone creates and publishes
// an instance of this subject, they are requesting someone show
// an analysis view based on data content,
public class AnalysisSubject
{
// subject content, in this case a data result from
// a business method
public object Data { get; set; }
}
public class MainWindow : ISubscriber<AnalysisSubject> ...
{
// use whatever implementation of an IoC container we like
// here i assume we abstract from implementation and use a
// custom interface IContainer that exposes functionality
// that we need
private readonly IContainer _container = null;
public class MainWindow ()
{
// we're teh r00tz! we create an instance of IoC
// container for use throughout application
IContainer _container = new CustomContainer ();
// our container exposes both parameterized and
// type-parameterized resolve methods
IEventHub events = _container.Resolve<IEventHub> ();
events.Subscribe<AnalysisSubject> (this);
}
#region ISubscriber<AnalysisSubject>
// part of strongly typed subscriptions is that we
// may now handle strongly typed publications! yay!
public void Receive (AnalysisSubject subject)
{
// 1. request to display analysis of data
Type analysisType = subject.Data.GetType ();
// 2. get view control based on payload type
//
// NOTE: implicit usage below is not consistent
// with previous invocations, here we are submitting
// a type of something we already have, and actually
// want back something that knows how to handle it.
// most IoC containers can provide this functionality
// through "facilities" add ons that accept a
// parameter\discriminator like below, and produce
// something in return.
Control control = (Control)(_container.Resolve (analysisType));
// [alternatively] if the above is too "magical" where
// IAnalysisFactory is an interface we define for this
// express purpose
//IAnalysisFactory factory = _container.Resolve<IAnalysisFactory> ();
//Control control = factory.GetAnalysisControlFor (analysisType);
// 3. assign subject data to control
Control.DataContext = subject.Data;
// 4. display control
}
#endregion
}
And an example of publication
public class SomeBusinessView
{
private readonly IEventHub _events = null;
// we cannot function without an event aggregator of
// some kind, so we declare our dependency as a contructor
// dependency
public SomeBusinessView (IEventHub events)
{
_events = events;
}
public void DoMyThang ()
{
// 1. do some business
MyBusinessData data = SomeBusinessFunction ();
// 2. publish complete event
AnalysisSubject subject = new AnalysisSubject () { Data = data, };
_events.Publish (subject);
}
}
Every View typically gets a viewmodel. If you are dealing with nested usercontrols inside one window, using multiple viewmodels (one per control) may be overkill.
If you have a viewmodel per control and are disconnected regarding communication between them then you can either have a common model that is universal to all the viewmodels OR have a global event provider that allows models to talk to eachother. (Something they all can reference for change notifications etc).
If you don't use a viewmodel per control then have the viewmodel bound to the main window in which all nested controls report to the main window which reports to the viewmodel for the main window.
Could the data source of the selection be bound to the types of ViewModels you have and the path possibly be the name of each (be it a string property for a formatted name or the Type name explicitly). On Selection you then have the relevant object that has been selected.
Possibly each of the ViewModels references a common provider which as you say performs the results analysis and the two different Views simply display the same data in different ways.

Accessing derived class from base class object issue

I have a kind of weird situation ...
I have a User Control in WPF witch in turn has some other User Controls attached to it, then I have a huge C# code file with a big algorithm which needs access to the User Control UI Elements and methods, this hole process works with a Timer which sends data to the C# code file algorithm from the User Control and it needs to return and update the UI elements from the control and also to access it's methods...
Now the thing is I don't want to put this huge algorithm in the codebehind file of my control, instead I would like to access the control's UI elements and declared methods from that code file ...
What I tried so far is to actually derive the code file's class from the User Control I use, this works fine and dandy but to access the derived class I need to create a new object of it and the UI that I get shown does not get updated since it also creates a new base class object I believe ...
so I have something like:
public partial class usrctrlSimulator : UserControl
{
public usrctrlSimulator()
{
this.InitializeComponent();
}
public void StartSimulator()
{
Algorithm = new csAlgorithm();
Algorithm.InitializeSimulator();
timer1.Start();
}
}
public class csAlgorithm : usrctrlSimulator
{
public csAlgorithm()
{
}
public void InitializeSimulator()
{
txtblkSimulatorStatus.Text = "Started"; // this element would be from the user control
}
}
So my question is : how do I call the derived class without instantiating a new object of it, since that will cause a new user control object to be created and the displayed UI will not be updated ... or if I don't derive the Algorithm class, what possibility do I have to access the user control elements and methods ?
If you want to stick with one instance of the control and still have access to the functionality in the derived class then you need to use the derived class as the control. So instead of an instance of usrctrlSimulator, you'd use csAlgorithm everywhere.
However, I'm not sure whether this design is the best approach in your scenario. The algorithm is not really a user control so maybe deriving from usrctrlSimulator is not the ideal option. For example: UserControl has a method called ApplyTemplate(). What would be the meaning of this in csAlgorithm? You can also look at it from a different angle: Would it be reasonable to use csAlgorithm wherever you could use UserControl, e.g. when invoking UserControl.AddLogicalChild(csAlgorithm)?
A different option would be to instantiate the algorithm as a member variable in usrctrlSimulator (composite). In that case you could still use it inside the usrctrlSimulator but you would have a clear separation of two concepts: A UserControl on one hand, and the implementation of an algorithm on the other hand. In addition you could then change either one of them with only limited impact on the other.
In that case your code would look as follows:
public partial class usrctrlSimulator : UserControl
{
public usrctrlSimulator()
{
this.InitializeComponent();
}
public void StartSimulator()
{
_algorithm= new csAlgorithm();
_algorithm.InitializeSimulator();
timer1.Start();
}
private csAlgorithm _algorithm;
}
public class csAlgorithm // not a UserControl anymore
{
public csAlgorithm()
{
}
public void InitializeSimulator()
{
txtblkSimulatorStatus.Text = "Started"; // this element would be from the user control
}
}

Categories

Resources