I am new to C# and i am making a Tic-Tac-Toe game in Visual Studio 2010. I've already made the whole structural part of it, but i am having trouble loading images from pictureBoxes. The command i am using is pictureBox.Load(string imageUrl), and it works fine when i use it on the method TicForm_Load, since TicForm is a Form:
private void TicForm_Load(object sender, EventArgs e)
{
//picture1 is the name of a pictureBox created on TicForm.cs (Design)
picture1.Load(imageUrl);
}
However, in my game, the changes to the images in the pictureBoxes are controlled by a class called Board. I want to be able to change images from this class.
I've already set the modifiers of the pictureBoxes to public, yet, if i want to access a command from TicForm, the program asks me to instantiate an object of the type TicForm first:
//Somewhere on the class Board
TicForm ticform = new Ticform();
ticform.picLocation00.Load(imageUrl);
This, however, causes an exception StackOverflow, since i create a new Board, at the start of the TicForm class, and i create a new TicForm, at the start of the Board class.
I would really appreciate an answer from someone with more experience / knowledge in Visual Studio than me. How do you normally change the images from the pictureBox in run-time? Am i doing something wrong?
It's been solved. Instead of using a method from TicForm into a class (which would never work), i created new variables on the class that indicate in what circustamces the method is to be used, and this happens inside the TicForm class.
Related
I'm developing an appliaction that has 2 forms and I ran into a problem. When I create a new instance of a class in Form2, then close Form2, I lose the instance values. So, I've solved this using static class, is this the correct approach?
The class name is Matriz_de_registracion and I have a function within it that's called "solver" that assigns values to the class properties ("Double MR0" is one of the variables as an example)
here's the code in Form2 (see I don't use the "new" statement otherwise once I close form2 I loose the instance values..
private void btn_iniciar_registro_de_puntos_Click(object sender, EventArgs e)
{
Matriz_de_Registracion.solver(_pois);
}
Then I can reference, in Form1, one of the properties of the Class by just doing this:
Matriz_de_Registracion.MR0
Now, is this correct approach or static classes are used for something else? I just wan to reference the values of the MR0 variable across all my forms without having to pass the instances through forms every time I open/close forms.
This is not the right approach. You should copy the values from the form object after it has closed but before you get rid of it.
The problem with using static data anything other than extremely sparingly is that you will find it makes the application much harder to work on as it gets larger - for example, you wouldn't be able to open two instances of the form at the same time, as they'd tread on each other's data.
Im using Visual C# 2010 express. Im working on a game, and have come accross a small, newbie problem. Thing is, i guess we're dealing with a best practise type situation, and none of the few beginner books i have really helped with it, so i hope you guys can.
So, i have two forms, one is a splashscreen/startup form and the other is the main game window. I made a class that contains all world data, and when in the first screen user clicks on "new game", a new instance of this class is generated and populated with data.
So far so good.
The newgame button, in addition to creating the world instance, opens up the main game window. The problem is, in the main game window, when i try to use attributes of the gameworld instance, it says that it doesnt exist in this context.
So, if i get it right, the created instance only exists within the first form class... is that correct?
So if i'd like to move that whole data, should i actually serialize and save the world class instance data, and load it in the second form? Or how should i approach this.
I understand it's a very newbie question, and i could propably hack it to work, but the thing is - i really feel like i have to understand everything im doing.
Thanks in advance!
You need to create a constructor on your game form that accepts an instance of your world class and assign it to a field of the same type - the field will be accessible to the game form methods.
World world;
// constructor
public GameForm (World world)
{
this.world = world;
}
// Can now use `world` in all `GameForm` methods
Instead of constructor injection (as I have shown in my example), you can use property injection, though I like the former better (tends to ensure proper initialization - though you may want to check for a null being passed in).
If there is a reference of the world data object in the splash screen, you can assign this to a public member in the main screen, or pass it to the main screen through a constructor.
so in the splash screen
FrmMain frmMain = new FrmMain();
frmMain.WorldData = this.WorldData;
if it is an instance member of the splash screen
or maybe something like
FrmMain frmMain = new FrmMain();
frmMain.WorldData = new WorldData();
or even
FrmMain frmMain = new FrmMain(this.WorldData);
or
FrmMain frmMain = new FrmMain(new WorldData());
with the FrmMain constructor as
public FrmMain(WorldData worldData)
{
this.m_WorldData = worldData;
}
Have a look at Passing Data Between Forms
Assuming you're using just windows forms, and not XNA or similar framework, where theres no winforms.
Startup form:
void StartButton_Click(object sender, EventArgs e)
{
GameWorld gw = new GameWorld();
// Initialize gw instance here
GameForm mainForm = new GameForm(gw);
mainForm.Show();
}
And add a constructor to the game form:
public class GameForm
{
private GameWorld _gw;
public GameForm()
{
InitializeComponent();
}
public GameForm(GameWorld gw) : this()
{
_gw = gw;
}
}
At that point you can use private variable _gw in the game form.
Also, i would suggest passing the GameWorld instance through the constructor, not the property as that value is crucial for the form. Generally properties might be better suited to provide a way to adjust some behavior, and any constructor parameter can be seen as mandatory for the object to work as it should.
You can also make default constructor (the one without parameters) private.
Depending on the size of the data and if the world object class is serializable, You might think about caching it. Then each form that needs the data can just get it from the cache whenever it is needed.
So I know it is bad to load content on constructor calls but is it ok to call a .load function for a class from the LoadContent()?
ex.
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
viewport = graphics.GraphicsDevice.Viewport;
player1.load(spriteBatch, Content);
}
Within the .load I would have Texture2D playerT = Content.Load<Texture2D>("player");
Is that ok? or what is the best way to handle multiple content that needs to be loaded?
The issue with loading things in a constructor call is that your likely going to want to unload content at times to save memory but keep an instance of the class around that way the class is ready to be used again by simply calling load(). So loading any time after the Game class initializes itself is fine and should be done based upon when the content is needed not a design convention.
So anytime past Game.Init is fine. And if the player class needs content right off the bat then calling load inside LoadContent() is the best place to do it.
Regarding "multiple content":
A subclass of the Game class inherits a ContentManager object called Content.
However, you're not limited to only this one ContentManager object (in fact you don't even have to use it at all). You can make as many as you need and put them anywhere you want. This is one way to handle differing content on different "screens" and such, so that you can load and UNload the pieces you need to.
To set up a different content manager in a different screen, you could do the following:
In a class somewhere, make a variable:
ContentManager moreContent;
Then initialize it like follows:
moreContent = new ContentManager(game.Services);
moreContent.RootDirectory = game.Content.RootDirectory;
You will have to pass your Game object into the class in order to initialize it properly. This will make this content manager have the same root folder as the parent Game.Content. Of course you can change this to whatever you like.
Now for this screen only, you can do stuff like:
Texture2D playerT = moreContent.Load<Texture2D>("player");
And then if you switch screens (on Update):
moreContent.Unload();
will take all the screen's content out of memory.
How do I call Zedgraph's function masterPane.SetLayout() from Web C# Application?
Basically i'm stuck at step myMasterPane.SetLayout(g, PaneLayout.SingleColumn);
How do I create that variable g which is supposed to be a Graphic()
I tried Graphics g = new Graphics(); and Graphics g;
none of these work.
new Graphics() gives me Error 2 The type 'System.Drawing.Graphics' has no constructors defined
and anyways I'm assuming this needs to be initialized somehow.
One important difference that I want to do vs the example below is that I want to go directly from my master pane to an image using
masterPane.GetImage(), my issue is I can't get that masterpane setup unless I find a way to call myMasterPane.SetLayout()
I found this article but I can't get this working
http://zedgraph.org/wiki/index.php?title=Use_a_MasterPane_in_a_web_page
The page you linked to shows exactly how to do this. Did you try their example?
The example gets the Graphics instance passed to it in the RenderGraph event handler.
I have a windows form with a listview control. I have a selectedIndex changed event where i am performing some action. Through reflection I am trying to set the value of the list view.
But the event is not getting fired. Any help will be helpfull.
Edit
The event looks like
private void LV1_SelectedIndexChanged(object sender, EventArgs e)
{
if (LV1.SelectedItems.Count>0)
{
if (LV1.SelectedItems[0].Text.ToString() == "testing")
{
// Do some work.
}
}
}
I am using relection in another project and changing the selected item as follows
Assembly a = Assembly.LoadFrom(exePath);
Type formType = a.GetType(formName);
testForm = (Form)a.CreateInstance(formType.FullName);
if (testForm != null)
{
Type t1 = testForm.GetType();
FieldInfo fi = t1.GetField(controlName, flags);
object ctrl = fi.GetValue(testForm);
ListView l1 = (ListView)ctrl;
l1.Items[0].Selected = true;
}
Automating another application is fun howver not a trivial task. There's a few options but I guess most of them is out of scope for you. One would be to programatically take over the mouse and keyboard and trough those channels manage the program. Another way would be to manipulate memory, As I said neither are trivial to implement and very easily broken if the aplpication is updated.
I would suggest instead of trying to automate the application to look for infliction points. Are there any service endpoints you could automate and achieve the same result? any API or dll's used by the application you could use instead?
If you really have to automate the application there do exist several frameworks for doing that (usually build for testing purposes). The only one I can think off right now is made by Assima as is ment for training purposes.
I think your problem is here:
testForm = (Form)a.CreateInstance(formType.FullName);
You are creating a new instance of the form. I'm assuming your main project is an exe that runs an shows the form. Your second project is then another exe that runs and wants to change the selected item. By creating a new instance of the form you will be changing the selected item on the new form, not the old one.
What you need to do is somehow pass the form object over to the secondary project. possibly some static method that gets a singleton instance of the form maybe.
I'm still not entirely sure why you are using reflection, you could just give the second project a reference to the first.
The first question I'd ask is: why are you using reflection here? Just set the value through the public API. If you are messing underneath the public API, then yes: it is entirely possible that some events won't get fired.
Perhaps if you could show us exactly how you are doing this?