I am really stuck in some sort of static-hell that I've placed myself into. I have a server and client. The client asks the server for a list of lobbies. The client creates a graphical lists of buttons for each lobby. Each lobby button has a reference to Matchmaking's static method JoinLobby as this seemed the most simple way to hook up n amount of lobby buttons.
However after a lobby button calls JoinLobby (static) I wanted the Matchmaking class to toggle off some UI elements that are public but not static. I want to avoid making these elements static if possible, because I am using Unity and it breaks the workflow of using Unity's built-in drag-and-drop reference creator.
public class LobbyButton{
public Button button;
public Text name;
public void JoinLobby(){
Matchmaking.JoinLobby(name.text);
}
}
public class Matchmaking{
public LobbyList lobbyList; // UI list element
public static void JoinLobby(string name){
JoinServerLobby(name);
lobbyList.Hide(); // can't do this, lobbyList not static
}
}
I've run in to this situation a few times and always end up doing some work-around or total redo. But I am wondering if there is a more common way of "getting out" of this static call.
In my opinion you have something wrong with your design.
Basically static means, that current member is a part of type, non an instance, thus mixing them to achieve some result, looks odd.
I think that you should inject Matchmaking to the LobbyButton button, store it as a field and reference to the non-static JoinLobby. I would leave static method to either utility tasks or generic functions, not related to the specific functionality.
Each lobby button has a reference to Matchmaking's static method JoinLobby as this seemed the most simple way to hook up n amount of lobby buttons.
Don't do that then.
In the form that has the "lobby buttons", keep a private variable with a reference to a Matchmaking instance. In the click events, refer to this variable.
You can also use the Tag property of buttons to give them an identifier, and hook them all up to the same click handler. There you check the Tag of the sender.
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
}
So I had a simple program that was roughly click a button and it preformed a task, nothing fancy, very simple. Now, I have added a LOT more features task for it to do. It does about 5 different main more complex tasks. The task have little input in the sense of like the common class/namespace examples dealing with insert name, address, phone number, etc. The task is more like set up the settings(check/uncheck the checkboxes) on how you want to preform the task and then click the button to preform it. The code has grown out of control. So I am now trying to organize it. I am self taught, so I am running into some trouble, but this is what I am thinking so far for organization. Any comments about the proper way to organize this would be appreciated.
namespace namespaceName
class task1Name
methods for task1
class task1Name
methods for task2
class task2Name
methods for task3
class task3Name
methods for task4
class task5Name
methods for task5
Now I also have a windows form for the program and another windows form for the pop up settings window. The big question is where do these fit in exactly? public partial class className : Form? Will this setup allow the methods in the different task classes to still interact with the form webbrowser control? The form has a couple of webbrowser controls and the task are prformed in the webbrowser control.
I guess in general I am just trying to find the best way to manage the code and to properly setup/structure the code. From reading this How to use separate .cs files in C#? maybe I just stick with the one class/file, since the task involve the webbrowser in windows form.
Ive been looking at http://msdn.microsoft.com/en-us/library/w2a9a9s3%28v=vs.100%29.aspx and the related sections listed below the code example
Breaking out your program into more maintainable chunks - the art of refactoring - can be a very challenging, but also a very rewarding, part of programming. Like #Keith said, you'll learn by doing.
The most important advice is to refactor in small, self-contained steps.
There are a number of ways that you could start this. If you want detailed advice, it would help to know what some of the code looks like. For example, what are the "task" methods' signatures (their names, arguments, and return type) and how do they interact with the "settings".
Here's one suggestion I would make. The single-responsibility principle suggests that the separate tasks should be in separate classes (and, usually, that means they should be in separate files - but that doesn't matter to the compiler at all, it's just for readability). If the tasks are in separate classes, they'll need a way to know what the settings on the form are. But the tasks don't care about the fact that the settings are on a form - they just want the values of the settings. So, create a data structure that contains all the settings from the form. Then, write a single method in the form class that reads all the settings from the controls, so you have that all in one place. Then, in your button click handler for each task's button, just call that method to get the settings, and pass the settings to the particular task that you're trying to run. Presto!
Your code would then look something like this: EDIT: I forgot that the WebBrowser control needs to be passed to the tasks. Fixed.
// Note: All classes and structs go in the same namespace, but each goes in its own .cs file.
// Use a struct, rather than a class, when you just need a small set of values to pass around
struct MySettings
{
public int NumberOfWidgets { get; set; }
public string GadgetFilename { get; set; }
public bool LaunchRocket { get; set; }
}
partial class MyForm
{
// ...constructor, etc.
private void ButtonForTask1_Clicked(object sender, EventArgs e)
{
var settings = ReadSettingsFromControls();
var task1 = new Task1(settings);
task1.DoTheTask(ref this.WebBrowserControl1);
}
private void ButtonForTask2_Clicked(object sender, EventArgs e)
{
var settings = ReadSettingsFromControls();
var task2 = new Task2(settings);
task2.DoTheTask(ref this.WebBrowserControl1);
}
// ... and so on for the other tasks
private MySettings ReadSettingsFromControls()
{
return new MySettings
{
NumberOfWidgets = int.Parse(this.txt_NumWidgetsTextBox.Text),
GadgetFilename = this.txt_GadgetFilenameTextBox.Text,
LaunchRocket = this.chk_LaunchPermission.Checked
};
}
}
class Task1
{
// Readonly so it can only be set in the constructor.
// (You generally don't want settings changing while you're running. :))
private readonly MySettings _settings;
public Task1(MySettings settings)
{
_settings = settings;
}
public void DoTheTask(ref WebBrowser browserControl)
{
// TODO: Do something with _settings.NumberOfWidgets and browserControl
// You can use private helper methods in this class to break out the work better
}
}
class Task2 { /* Like Task1... */ }
Hope that helps! Again, if you post some example code, you'll probably get much better advice on how to refactor it.
In the form.cs file I have two buttons,a memo and a timer.My question is: How do I access the timer or the memo from another cs file?
I've tried to make the objects public,but it didn't work,please give me a source or a project,so I can see where I'm mistaken.
Thanks!
Select your button in designer, go to it's properties and change "Modifiers" property from Private to Public.
Then you can get access to it from another class, something like this:
public static class Test
{
public static void DisalbeMyButton()
{
var form = Form.ActiveForm as Form1;
if (form != null)
{
form.MyButton.Enabled = false;
}
}
}
Note: it's just an example and definitely not a pattern for good design :-)
I worry whenever I hear someone talking about "another .cs file" or "another .vb file". It often (though not always) indicates a lack of understanding of programming, at least of OO programming. What's in the files? One class? Two?
You're not trying to access these things from another file, you're trying to access them from a method of a class, or possibly of a module in VB.
The answer to your question will depend on the nature of the class and method from which you're trying to access these things, and the reason why you want to access them.
Once you edit your question to include this information, the answers you receive will probably show you that you shouldn't be accessing these private pieces of the form in classes other than the form class itself.
There is Form object already instanced in Program.cs, except it have no reference. With simple editing you can turn
Application.Run(new Form1());
to
Application.Run(formInstance = new Form1());
declare it like
public static Form1 formInstance;
and use
Program.formInstance.MyFunction(params);
Although I agree with John Saunders, one thing you may be doing wrong, assuming that you have everything accessible through public modifiers, is that you don't have the instance of that form.
For example, this is how you would do it:
Form1 myForm = new Form1;
string theButtonTextIAmLookingFor = myForm.MyButton.Text;
I am assuming that you may be trying to access it like it's static, like this:
string theButtonTextIAmLookingFor = Form1.MyButton.Text;
Just something you might want to check.
The intuitive option is simply to make the control field public
Here is a very good solution to solve this issue..
http://searchwindevelopment.techtarget.com/answer/In-C-how-can-I-change-the-properties-of-controls-on-another-form
First off, this is a question about a desktop application using Windows Forms, not an ASP.NET question.
I need to interact with controls on other forms. I am trying to access the controls by using, for example, the following...
otherForm.Controls["nameOfControl"].Visible = false;
It doesn't work the way I would expect. I end up with an exception thrown from Main. However, if I make the controls public instead of private, I can then access them directly, as so...
otherForm.nameOfControl.Visible = false;
But is that the best way to do it? Is making the controls public on the other form considered "best practice"? Is there a "better" way to access controls on another form?
Further Explanation:
This is actually a sort of follow-up to another question I asked, Best method for creating a “tree-view preferences dialog” type of interface in C#?. The answer I got was great and solved many, many organizational problems I was having in terms of keeping the UI straight and easy to work with both in run-time and design-time. However, it did bring up this one niggling issue of easily controlling other aspects of the interface.
Basically, I have a root form that instantiates a lot of other forms that sit in a panel on the root form. So, for instance, a radio button on one of those sub-forms might need to alter the state of a status strip icon on the main, root form. In that case, I need the sub-form to talk to the control in the status strip of the parent (root) form. (I hope that makes sense, not in a "who's on first" kind of way.)
Instead of making the control public, you can create a property that controls its visibility:
public bool ControlIsVisible
{
get { return control.Visible; }
set { control.Visible = value; }
}
This creates a proper accessor to that control that won't expose the control's whole set of properties.
I personally would recommend NOT doing it... If it's responding to some sort of action and it needs to change its appearance, I would prefer raising an event and letting it sort itself out...
This kind of coupling between forms always makes me nervous. I always try to keep the UI as light and independent as possible..
I hope this helps. Perhaps you could expand on the scenario if not?
The first is not working of course. The controls on a form are private, visible only for that form by design.
To make it all public is also not the best way.
If I would like to expose something to the outer world (which also can mean an another form), I make a public property for it.
public Boolean nameOfControlVisible
{
get { return this.nameOfControl.Visible; }
set { this.nameOfControl.Visible = value; }
}
You can use this public property to hide or show the control or to ask the control current visibility property:
otherForm.nameOfControlVisible = true;
You can also expose full controls, but I think it is too much, you should make visible only the properties you really want to use from outside the current form.
public ControlType nameOfControlP
{
get { return this.nameOfControl; }
set { this.nameOfControl = value; }
}
After reading the additional details, I agree with robcthegeek: raise an event. Create a custom EventArgs and pass the neccessary parameters through it.
Suppose you have two forms, and you want to hide the property of one form via another:
form1 ob = new form1();
ob.Show(this);
this.Enabled= false;
and when you want to get focus back of form1 via form2 button then:
Form1 ob = new Form1();
ob.Visible = true;
this.Close();
I would handle this in the parent form. You can notify the other form that it needs to modify itself through an event.
Use an event handler to notify other the form to handle it.
Create a public property on the child form and access it from parent form (with a valid cast).
Create another constructor on the child form for setting form's initialization parameters
Create custom events and/or use (static) classes.
The best practice would be #4 if you are using non-modal forms.
You can
Create a public method with needed parameter on child form and call it from parent form (with valid cast)
Create a public property on child form and access it from parent form (with valid cast)
Create another constructor on child form for setting form's initialization parameters
Create custom events and/or use (static) classes
Best practice would be #4 if you are using non-modal forms.
With the property (highlighted) I can get the instance of the MainForm class. But this is a good practice? What do you recommend?
For this I use the property MainFormInstance that runs on the OnLoad method.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LightInfocon.Data.LightBaseProvider;
using System.Configuration;
namespace SINJRectifier
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
UserInterface userInterfaceObj = new UserInterface();
this.chklbBasesList.Items.AddRange(userInterfaceObj.ExtentsList(this.chklbBasesList));
MainFormInstance.MainFormInstanceSet = this; //Here I get the instance
}
private void btnBegin_Click(object sender, EventArgs e)
{
Maestro.ConductSymphony();
ErrorHandling.SetExcecutionIsAllow();
}
}
static class MainFormInstance //Here I get the instance
{
private static MainForm mainFormInstance;
public static MainForm MainFormInstanceSet { set { mainFormInstance = value; } }
public static MainForm MainFormInstanceGet { get { return mainFormInstance; } }
}
}
I agree with using events for this. Since I suspect that you're building an MDI-application (since you create many child forms) and creates windows dynamically and might not know when to unsubscribe from events, I would recommend that you take a look at Weak Event Patterns. Alas, this is only available for framework 3.0 and 3.5 but something similar can be implemented fairly easy with weak references.
However, if you want to find a control in a form based on the form's reference, it's not enough to simply look at the form's control collection. Since every control have it's own control collection, you will have to recurse through them all to find a specific control. You can do this with these two methods (which can be improved).
public static Control FindControl(Form form, string name)
{
foreach (Control control in form.Controls)
{
Control result = FindControl(form, control, name);
if (result != null)
return result;
}
return null;
}
private static Control FindControl(Form form, Control control, string name)
{
if (control.Name == name) {
return control;
}
foreach (Control subControl in control.Controls)
{
Control result = FindControl(form, subControl, name);
if (result != null)
return result;
}
return null;
}
#Lars, good call on the passing around of Form references, seen it as well myself. Nasty. Never seen them passed them down to the BLL layer though! That doesn't even make sense! That could have seriously impacted performance right? If somewhere in the BLL the reference was kept, the form would stay in memory right?
You have my sympathy! ;)
#Ed, RE your comment about making the Forms UserControls. Dylan has already pointed out that the root form instantiates many child forms, giving the impression of an MDI application (where I am assuming users may want to close various Forms). If I am correct in this assumption, I would think they would be best kept as forms. Certainly open to correction though :)
Do your child forms really need to be Forms? Could they be user controls instead? This way, they could easily raise events for the main form to handle and you could better encapsulate their logic into a single class (at least, logically, they are after all classes already).
#Lars: You are right here. This was something I did in my very beginning days and have not had to do it since, that is why I first suggested raising an event, but my other method would really break any semblance of encapsulation.
#Rob: Yup, sounds about right :). 0/2 on this one...
You should only ever access one view's contents from another if you're creating more complex controls/modules/components. Otherwise, you should do this through the standard Model-View-Controller architecture: You should connect the enabled state of the controls you care about to some model-level predicate that supplies the right information.
For example, if I wanted to enable a Save button only when all required information was entered, I'd have a predicate method that tells when the model objects representing that form are in a state that can be saved. Then in the context where I'm choosing whether to enable the button, I'd just use the result of that method.
This results in a much cleaner separation of business logic from presentation logic, allowing both of them to evolve more independently — letting you create one front-end with multiple back-ends, or multiple front-ends with a single back-end with ease.
It will also be much, much easier to write unit and acceptance tests for, because you can follow a "Trust But Verify" pattern in doing so:
You can write one set of tests that set up your model objects in various ways and check that the "is savable" predicate returns an appropriate result.
You can write a separate set of that check whether your Save button is connected in an appropriate fashion to the "is savable" predicate (whatever that is for your framework, in Cocoa on Mac OS X this would often be through a binding).
As long as both sets of tests are passing, you can be confident that your user interface will work the way you want it to.
This looks like a prime candidate for separating the presentation from the data model. In this case, your preferences should be stored in a separate class that fires event updates whenever a particular property changes (look into INotifyPropertyChanged if your properties are a discrete set, or into a single event if they are more free-form text-based keys).
In your tree view, you'll make the changes to your preferences model, it will then fire an event. In your other forms, you'll subscribe to the changes that you're interested in. In the event handler you use to subscribe to the property changes, you use this.InvokeRequired to see if you are on the right thread to make the UI call, if not, then use this.BeginInvoke to call the desired method to update the form.
Step 1:
string regno, exm, brd, cleg, strm, mrks, inyear;
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
string url;
regno = GridView1.Rows[e.NewEditIndex].Cells[1].Text;
exm = GridView1.Rows[e.NewEditIndex].Cells[2].Text;
brd = GridView1.Rows[e.NewEditIndex].Cells[3].Text;
cleg = GridView1.Rows[e.NewEditIndex].Cells[4].Text;
strm = GridView1.Rows[e.NewEditIndex].Cells[5].Text;
mrks = GridView1.Rows[e.NewEditIndex].Cells[6].Text;
inyear = GridView1.Rows[e.NewEditIndex].Cells[7].Text;
url = "academicinfo.aspx?regno=" + regno + ", " + exm + ", " + brd + ", " +
cleg + ", " + strm + ", " + mrks + ", " + inyear;
Response.Redirect(url);
}
Step 2:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string prm_string = Convert.ToString(Request.QueryString["regno"]);
if (prm_string != null)
{
string[] words = prm_string.Split(',');
txt_regno.Text = words[0];
txt_board.Text = words[2];
txt_college.Text = words[3];
}
}
}
public void Enable_Usercontrol1()
{
UserControl1 usercontrol1 = new UserControl1();
usercontrol1.Enabled = true;
}
/*
Put this Anywhere in your Form and Call it by Enable_Usercontrol1();
Also, Make sure the Usercontrol1 Modifiers is Set to Protected Internal
*/
Change modifier from public to internal. .Net deliberately uses private modifier instead of the public, due to preventing any illegal access to your methods/properties/controls out of your project. In fact, public modifier can accessible wherever, so They are really dangerous. Any body out of your project can access to your methods/properties. But In internal modifier no body (other of your current project) can access to your methods/properties.
Suppose you are creating a project, which has some secret fields. So If these fields being accessible out of your project, it can be dangerous, and against to your initial ideas. As one good recommendation, I can say always use internal modifier instead of public modifier.
But some strange!
I must tell also in VB.Net while our methods/properties are still private, it can be accessible from other forms/class by calling form as a variable with no any problem else.
I don't know why in this programming language behavior is different from C#. As we know both are using same Platform and they claim they are almost same Back end Platform, but as you see, they still behave differently.
But I've solved this problem with two approaches. Either; by using Interface (Which is not a recommend, as you know, Interfaces usually need public modifier, and using a public modifier is not recommend (As I told you above)),
Or
Declare your whole Form in somewhere static class and static variable and there is still internal modifier. Then when you suppose to use that form for showing to users, so pass new Form() construction to that static class/variable. Now It can be Accessible every where as you wish. But you still need some thing more.
You declare your element internal modifier too in Designer File of Form. While your Form is open, it can be accessible everywhere. It can work for you very well.
Consider This Example.
Suppose you want to access to a Form's TextBox.
So the first job is declaration of a static variable in a static class (The reason of static is ease of access without any using new keywork at future).
Second go to designer class of that Form which supposes to be accessed by other Forms. Change its TextBox modifier declaration from private to internal. Don't worry; .Net never change it again to private modifier after your changing.
Third when you want to call that form to open, so pass the new Form Construction to that static variable-->>static class.
Fourth; from any other Forms (wherever in your project) you can access to that form/control while From is open.
Look at code below (We have three object.
1- a static class (in our example we name it A)
2 - Any Form else which wants to open the final Form (has TextBox, in our example FormB).
3 - The real Form which we need to be opened, and we suppose to access to its internal TextBox1 (in our example FormC).
Look at codes below:
internal static class A
{
internal static FormC FrmC;
}
FormB ...
{
'(...)
A.FrmC = new FormC();
'(...)
}
FormC (Designer File) . . .
{
internal System.Windows.Forms.TextBox TextBox1;
}
You can access to that static Variable (here FormC) and its internal control (here Textbox1) wherever and whenever as you wish, while FormC is open.
Any Comment/idea let me know. I glad to hear from you or any body else about this topic more. Honestly I have had some problems regard to this mentioned problem in past. The best way was the second solution that I hope it can work for you. Let me know any new idea/suggestion.