I have made a windows form application (which has been running fine for more than couple of weeks). Now I wanted to add another form in it (which should be displayed to show extra properties of item whose value is being shown in rich textbox)
Here is my code for double click (to show details window):
private void richTextBox1_DoubleClick(object sender, EventArgs e)
{
//Using parameterized constructor since I need an input from parent form
Form2 formETView = new Form2(richTextBox1.Text.Substring(1, 15));
formETView.Show();
}
As a reference, constructor of Form2 is:
public Form2(string p)
{
// TODO: Complete member initialization
trans_ID = p;
}
But it shows only this screen:
While actual screen has couple of controls:
Any help in this regard will be really appreciated.
P.S: Is the approach to use parameterized constructor to pass data as argument in child window incorrect? Please let me know if it's the case.
Use
public Form2(string p) : this()
This way you call default constructor that calls InitializeComponents.
Just call InitializeComponent() in your constructor function. That initializes all the controls of the form.
Related
It's probably a silly question, but I really don't know how to handle it.
My main form default class looks like this:
public partial class MainForm : Form
{
public MainForm(bool version)
{
InitializeComponent();
if(version == true)
{
items_checkedListBox.Items.Add("aa".ToString());
}
else
{
Controls.Remove(items_checkedListBox);
}
}
}
By default, my WinForm app starts with Application.Run(new MainForm(true)); and everything is ok. But I want to update the checkedListBox from another class and for that I need to instantiate my main form object and I call the new object with MainForm mainForm = new MainForm(false); but the problem is that the checkedList control remains, even though Controls.Remove(items_checkedListBox); gets executed.
How could I manipulate a control from another class when I instantiate the main form? :(
By doing this:
MainForm mainForm = new MainForm(false);
you create a new second form of the type MainForm and delete it's control items_checkedListBox, but that's not the control which you see on your first form of MainForm. Furthermore you don't see the second form you created, because you didn't make it show up, so don't wonder that you don't see anything happening like the removal of the other control on the second form.
So in order to manipulate your control items_checkedListBox you need to pass the reference of this control to your class in which you wish to manipulate it.
Imagine you would have another form (which is your other class), which you use to manipulate your control items_checkedListBox.
public partial class FmManipulateControl : Form
{
public FmManipulateControl()
{
InitializeComponent();
}
}
In order to be able to do this, pass a reference of this control as method parameter to the constructor:
public FmManipulateControl(Control myControl) { ... }
So that we can manipulate it we store this reference of our control in a field, so e.g. a button click event can access the control to change/remove/... it.
Control controlToChange;
public FmManipulateControl(Control myControl)
{
InitializeComponent();
controlToChange = myControl;
}
Let's imagine we bind to a button click event in our form FmManipulateControl:
private void button1_Click(object sender, EventArgs e)
{
//diposes the control, so it does not exist anymore, but you can apply
//any change to the control you wish to do
controlToChange.Dispose();
}
Now all you have to do is to create an instance of FmManipulateControl and pass it a reference of the control items_checkedListBox and show the new form object.
FmManipulateControl fmChangeAControl = new FmManipulateControl( items_checkedListBox);
fmChangeAControl.Show();
Further explaination about the reference type:
I am talking about passing a reference of the control and I think you might wonder about what I mean by that. I suggest you to read about value and reference types.
I try to keep it short and simple.
Imagine a value type contains the value directly itself: e.g. an int. The object contains the value directly.
int a = 3;
a contains the value 3.
Now let's have a look at our control. This ListBox control items_checkedListBox does not contain our object control, but a reference to it's location in memory. That's why it is called reference type.
So when we pass items_checkedListBox as a method parameter, we don't pass an object, but the memory location of our items_checkedListBox control. So we point to the same object, so we are abel to manipulate it.
Note:
Method parameters are just a copy of the inputted object, so when we do:
FmManipulateControl fmChangeAControl = new FmManipulateControl( items_checkedListBox);
In our form fmChangeAControl we got an object(myControl) which is a copy of items_checkedListBox. But since we did not pass the object, but a reference it does not matter if we have a copy or not, we still point to the same memory location so we still manipulate the same object.
In my program I have two forms. The main form and a form where you fill in extra information. What I'm trying to do is to write out the information given on the second form on a list box when the 'ok' button is pressed.
Currently this is what I have:
Main form:
public void writeLine()
{
foreach (var item in VarClass.listItems[VarClass.count - 1])
{
listBox1.Items.Add(item.ToString());
}
}
Second form:
Form1.writeLine();
As it, I get the following error at 'Form1.writeLine();'
"An object reference is required for the non-static field, method or property..."
I can kinda fix this by making 'writeLine()' static in the main form, but then I get the same error on 'listBox1' in the main form. How do I fix this?
You should pass the reference of your main form to the second form and call the method on that reference. For example you can create a property on the second form like private Form _mainForm; and create a constructor of the second form to receive that reference and set to that field. After that you will be able to call _mainForm.writeLine() in your second form.
Create an instance of Form1 and call the method. Here is the code:
new Form1().writeLine();
There are a couple ways to handle this. One is for form2 to have a reference back to the calling form ideally through an interface rather than a reference to the concrete class.
Another option would be for Form2 to have an event that form1 could subscribe to that would inform form1 that form2 has some output.
Keep a reference to the second form from the first:
public MyFirstForm
{
...
public MyFunction()
{
MySecondForm secondForm = new MySecondForm();
// ... Open your form etc, look for when it's complete and then ...
// Read the values from the second form into the first
var MyValues = secondForm.getValues();
// Now populate the list-box with the information returned.
//for (my listbox)
}
}
I'm making a game library with C#.
I have a main Form which has a FlowLayoutPanel, which hosts the game library. There is an "add game" method in main Form which adds an item to FlowLayoutPanel, but this method is being called from a second form. But when I'm calling this method from this second form, nothing happens at all, but it works, if called from the main form.
Here's the code:
Here's the add game method in mainForm:
public void addIso()
{
PictureBox gameBox = new PictureBox();
gameBox.ImageLocation = "link here";
gameBox.Height = 200;
gameBox.Width = 150;
gameBox.SizeMode = PictureBoxSizeMode.StretchImage;
isoPanel.Controls.Add(gameBox);
}
This method adds a placeholder game to FlowLayoutPanel called isoPanel. Works when called from the same form.
And here's how the method is being called from second form:
private void addGameButton_Click(object sender, EventArgs e)
{
MainWindow mainForm = new MainWindow();
mainForm.addIso();
}
When I tried to add simple message box in the method, message box did show, but game wasn't added to FlowLayoutPanel.
Any tips or solutions?
I apologize for my poor english and messy programming terms, I started learning C# a little while ago.
You can achieve this by using delegate and Delegate.
What you are doing wrong here:
From addGameButton click event you are creating a new instance of the mainForm. Which is not the actual main form that you are currently seeing, its a different instance of the mainForm. your code adds the control to the layout just confirm this by calling mainForm.Show() this will opens a new form with the control.
What you can do:
In such cases, you want to modify the parent control, calling methods in parent class, you need to use delegates by the following way:
Changes needs to apply in the Parent class ie., MainWindow.
Define a delegate and an event of that delegate type.
public delegate void UpdateUiDelegate();
public event UpdateUiDelegate UpdateUiEvent;
Assign the required method to the Event(better use this in constructor):
public MainWindow ()
{
UpdateUiEvent+= new UpdateUiDelegate(addIso);
}
Next work is in the child form ie., Form2 (use a better name let it be ImageChildControl). Create a Delegate there:
public Delegate ControlCreator;
Come back to MainWindow, Locate the place where you are calling the Second form, after creating instance of the child form assign the created event to that Delegate of the instance, for that Use the following codes there:
ImageChildControl ImageChildControlInstance = new ImageChildControl();
ImageChildControlInstance.ControlCreator = UpdateUiEvent;
One more work to do in child form that is; Calling the delegate from the Button click event. ie.,
private void addGameButton_Click(object sender, EventArgs e)
{
ControlCreator.DynamicInvoke();
}
Now you can see your code works as you expected.
You seem to be recreating the form when you load the second form.
as this does lack a little context.
I suggest you have a main tread which will run the two forms
create a game manager class Ex: GameManager.cs
In the class create a variable for both forms and set them as protected.
in each form send a reference of the gamemanager to it.
which will allow each window to communicate with each other through the manager by provide secure inter communication.
Let me know if you would like some source with this.
I'm fairly new to Visual C# and I'm writing an GUI app with multiple forms. One form is main window, and the rest are some kind of option windows. When showing an option window, I need to load some data to it (for example a string to window's editbox), then edit it and return back to main window when closing option window. Is there any simple way I can achieve it?
I've found some solutions like, or c# event handling between two forms, but I can't really conform it to my needs. I was thinking about passing data in constructor, but how to get it back? I've found something about ShowDialog, but as I said I'm new to C# (started yesterday ^^) and don't know if I can use it.
Any ideas, please?
I found the following previous answer which outlines sending specific properties from the one form to another:
Send values from one form to another form
The using keyword will also ensure that the form is cleaned-up properly, here's a link to it's usage (pardon the pun...) : http://msdn.microsoft.com/en-us/library/vstudio/yh598w02.aspx
I've run into the same issue to be honest, and I have to say that prior to this discussion I would just pass the parent form itself to the child and alter it in that way. Such as:
ChildForm child = new ChildForm(this); //from the parent
and
public ChildForm(ParentForm parent)
{
this.parent = parent;
}
Probably not the best convention though, as you probably don't need to access that much from the parent as the child.
Thanks guys, I think I finally get it. Idle_Mind, your idea was the easiest in my point of view, so I decided to use it. If someone else has a problem like this, here's what I've coded:
In main window form: when button is clicked, a new form appears; after closing it, label1 shows the text typed in that form
private void Button1_Click(object sender, EventArgs e)
{
LoadDataForm loaddata = new LoadDataForm("initial value");
if (loaddata.ShowDialog() == DialogResult.OK)
{
label1.Text = loaddata.textBox1.Text;
}
}
In load data form: argument passed in form's constructor appears in textBox1; textBox1's Modifiers property has to be modified to "public"
public LoadDataForm(string initvalue)
{
InitializeComponent();
textBox1.Text = initvalue;
}
private void ApplyButton_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
}
Regards,
mopsiok
I want to update label of Form1 from Form2. So here's what I have:
// Form1
public string Label1
{
get { return this.label1.Text; }
set { this.label1.Text = value; }
}
// Form2
private void button1_Click(object sender, EventArgs e)
{
Form1 frm1 = new Form1();
frm1.Label1 = this.textBox1.Text;
this.Close();
}
So the above code doesn't work. However, when I add the following:
frm1.Show();
after
this.Close();
in Form2 code, the Form1 obviously is being opened again (two windows). But I want it to update in the same window so I suggest this.Close() is unnecessary.
Anyone have any ideas?
In the button1_Click method, you're actually creating a new instance of Form1 and setting the Label1 property of that new instance. That explains why a second instance of Form1 is being shown on the screen when you add frm1.Show();. If you look at that second copy carefully, you'll see that it's label displays the correct value, but your original copy of that form retains its original value.
Instead, I assume that what you want to do is set the Label1 property for the existing instance of Form1 that is already displayed on the screen. In order to do that, you're going to have to get a reference to that existing form object.
Thus, this becomes a simple question of "how do I pass data between two objects (forms)", which has been asked countless times here on Stack Overflow. See the answers to these related questions:
Communicate between two windows forms in C#
Passing values between two windows forms
C# beginner help, How do I pass a value from a child back to the parent form?
Send values from one form to another form in c# winforms application
Try using singleton design pattern for that as I think the problem is when you using new
public class Form1Singleton {
private static final Form1Singleton INSTANCE = null;
// Private constructor prevents instantiation from other classes
private Form1Singleton () {
}
public static Form1Singleton getInstance()
{
if(INSTANCE ==null)
INSTANCE =new Form1Singleton();
return INSTANCE;
}
}
Now you can use the form easily only 1 form
private void button1_Click(object sender, EventArgs e)
{
Form1Singleton frm1 = Form1Singleton.getInstance();
frm1.Label1 = this.textBox1.Text;
this.Close();
}
I hope that solve your problem
BR,
Mohammed Thabet Zaky
Most probably: What you actually do is create a brand new instance of Form1 within the scope of Form2, while later in the control flow of your program another instance of Form1 is created and shown. Of course, in such a case you can't expect your label to be set correctly.
The best would be to decouple Form1 and Form2 from each other and instead pass only data along the control flow of your program.
When you say this.close that means all the values you set to that instance gets nullifies.
You can use delegate here, to set form values.
MVP pattern is good for this type of senario and also separate UI and business logic.
This thread is good reference:
UI Design Pattern for Windows Forms (like MVVM for WPF)