Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
i'm making a little application and i don't know how to open new window of app with parameters of clicked button.
For example: If i click to hydrogen, i want to open form called prvek, which will display informations about it.
Sorry for my bad English. Here's screenshot of main window:
Main window
Opening a form in Windows Forms simply involves creating an instance of that form and calling .Show() on that instance. For example:
var someForm = new SomeForm();
someForm.Show();
If you want to pass values to that form, you can set them as constructor arguments. For example, in SomeForm:
public SomeForm(int someValue)
{
// do something with someValue
}
Then when you create it:
var someForm = new SomeForm(aValue);
someForm.Show();
Or if the values aren't necessarily required, but you happen to have them available at this time, maybe set them as properties. In SomeForm:
public int SomeValue { get; set; }
Then when you create it:
var someForm = new SomeForm();
someForm.SomeValue = aValue;
someForm.Show();
or:
var someForm = new SomeForm { SomeValue = aValue };
someForm.Show();
Where you get your values, of course, is up to you. I'm not sure what you mean by "parameters of the clicked button". But in the click event there should be an object sender which is a reference to the UI element that triggered the event.
So, for example, if you want a property from the Button that was clicked, you can cast sender to Button and read its information. Something like this:
var buttonText = ((Button)sender).Text;
You should be able to give your second form, prvek, a property that you can set from your first. For example:
public string Element { get; private set; };
Then, in your button_onClick method you should be able to do the following:
ElementForm myForm = new ElementForm(); //Whatever the class name is of your second form
myForm.Element = ((Button)this).Name; //Get the name of the button
myForm.Show();
In your second form's constructor or initializer method, you'll want to set the title of the form:
public ElementForm()
{
InitializeComponent()
this.Text = Element;
}
Related
Wierd behaviour when passing values to and from second form.
ParameterForm pf = new ParameterForm(testString);
works
ParameterForm pf = new ParameterForm();
pf.testString="test";
doesn't (testString defined as public string)
maybe i'm missing something? Anyway I'd like to make 2nd variant work properly, as for now - it returns null object reference error.
Thanks for help.
Posting more code here:
calling
Button ParametersButton = new Button();
ParametersButton.Click += delegate
{
ParameterForm pf = new ParameterForm(doc.GetElementById(ParametersButton.Tag.ToString()));
pf.ShowDialog(this);
pf.test = "test";
pf.Submit += new ParameterForm.ParameterSubmitResult(pf_Submit);
};
definition and use
public partial class ParameterForm : Form
{
public string test;
public XmlElement node;
public delegate void ParameterSubmitResult(object sender, XmlElement e);
public event ParameterSubmitResult Submit;
public void SubmitButton_Click(object sender, EventArgs e)
{
Submit(this,this.node);
Debug.WriteLine(test);
}
}
result:
Submit - null object reference
test - null object reference
pf.ShowDialog(this); is a blocking call, so pf.Submit += new ParameterForm.ParameterSubmitResult(pf_Submit); is never reached: switch the order.
Submit(this,this.node); throws a null object reference because no event is assigned to it (see above). Generally, you should always check first: if (Submit != null) Submit(this,this.node);
You should change ``pf.ShowDialog(this);topf.Show(this);` so that your main form isn't disabled while your dialog box is open, if that's what you want, or use the model below (typical for dialog boxes.)
I'm not sure what pf_Submit is supposed to do, so this might not be the best way to go about it in your application, but it's how general "Proceed? Yes/No" questions work.
Button ParametersButton = new Button();
ParametersButton.Click += delegate
{
ParameterForm pf = new ParameterForm(testString);
pf.ShowDialog(this); // Blocks until user submits
// Do whatever pf_Submit did here.
};
public partial class ParameterForm : Form
{
public string test; // Generally, encapsulate these
public XmlElement node; // in properties
public void SubmitButton_Click(object sender, EventArgs e)
{
Debug.WriteLine(test);
this.Close(); // Returns from ShowDialog()
}
}
When you want to use your second variant, you have to use a getString()-Method, where you can put the e.g. "testString". The way you wrote it, "testString" should be a method (and got brackets).
EDIT (a bit more precise):
You could write:
pf.getString(testString);
, if "pf" is an instance of your own class, otherwise you had to look up, whether you can retrieve a String in this class.
the thing was in line order :)
pf.Submit += new ParameterForm.ParameterSubmitResult(pf_Submit);
and
pf.Test = "test";
should have been set before
pf.ShowDialog(this);
my mistake thingking that parameter can be passed after 2nd form was displayed
thnx for answers
I have a button on a completion form, which when pressed opens up a windows explorer.
This was ok, when i only had 1 directory.
I now have 2 directories, which are now set from my main form.
What i would like to do, is when the button is pressed, if a combobox on my main form is for example "Apples" then opens up a coded directory.
If the combobox on my main for is "Pears" then open up a different directory.
I have the following code to open up the original directory - just dont know how to include the second, as i cant seem to access the combobox from the completion form:
private void button1_Click(object sender, EventArgs e)
{
{
this.Hide();
FrmMain form3 = new FrmMain();
form3.Show();
}
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo()
{
FileName = "C:\\Directory 1\\",
UseShellExecute = true,
Verb = "open"
});
}
Hope you can help.
Thanks - Craig.
There are quite a few ways you could do this. I'm supposing your completion form is opened from the main form. The cleanest way would be to inject the current selection of the main form's combobox upon creation. Something in the line of:
var completionForm = new CompletionForm(directoryCombo.Text);
completionForm.ShowDialog(this);
Do note that ShowDialog is relevant. This ensures that no one will change the selected directory while the completion form is active. If this not the case, and the completion form isn't modal, then a better alternative is to implement a public property in your main form:
public string SelectedDirectory => directoryCombo.Text;
And then simply access it form your completion form:
var selectedDirectory = (Owner as mainForm).SelectedDirectory;
Let's say your mainform class is called MainForm and that the combobox instance inside it is called directoryComboBox.
Now, the first step consists in creating a property in your MainForm that exposes the currently selected value of the directoryComboBox instance:
public String CurrentDirectory
{
get { return directoryComboBox.Text; }
}
In your CompletionForm class, add the following field (used as a reference to the parent MainForm instance):
private MainForm m_Parent;
and modify the constructor as follows:
public CompletionForm(MainForm parent)
{
m_Parent = parent;
}
Finally, modify the code of your MainForm in which you create a new completion form and show it to the user as follows:
CompletionForm cf = new CompletionForm(this); // this is the current instance of `MainForm` showing the completion form
cf.ShowDialog(this);
In your CompletionForm you can now have access to the currently selected value of your directoryComboBox:
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo()
{
FileName = Path.Combine(#"C:\", m_Parent.CurrentDirectory),
UseShellExecute = true,
Verb = "open"
});
You could also construct your CompletionForm instance by directly passing it the current directoryComboBox value. The approach is very similar and it doesn't require you to modify your MainForm class adding a new property. All you have to do is to edit the right CompletionForm portions of code:
private String m_CurrentDirectory;
public CompletionForm(String currentDirectory)
{
m_CurrentDirectory = currentDirectory;
}
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo()
{
FileName = Path.Combine(#"C:\", m_CurrentDirectory),
UseShellExecute = true,
Verb = "open"
});
and the MainForm method that instantiates it:
CompletionForm cf = new CompletionForm(directoryComboBox.Text);
cf.ShowDialog(this);
So i am trying to store my main form and open a new one however i get this error, here is the code:
I have this at form level
public static frmAddBook frmkeepBooks = null;
public frmMain()
{
InitializeComponent();
frmkeepBooks = this;
}
The error underlines "this" saying it "Cannot inplicitly convert type Books.frmMain to Books.frmAddBook"
Change the first line into:
public static frmMain frmkeepBooks = null;
The types should be equal (or in herited) and probably it is not.
Are you trying to just show the new form on top of the old as a dialog keeping the old form up? I don't quite understand why you are trying to set your instance of frmMain to equal a null instance of frmAddBook.
if you are trying to open new form as a dialog you would do something like this:
public static frmAddBook frmkeepBooks;
public frmMain()
{
InitializeComponent();
frmKeepBooks = new frmAddBook();
/* if you want to display the 2nd form ontop of the first disallowing
user interaction on the first until the 2nd form closes */
frmKeepBooks.ShowDialog();
// If you want to allow interaction on either form
frmKeepBooks.Show();
/* maybe you don't want to display the first form
anymore after the 2nd form is displayed */
this.Visible = false;
}
I think this question needs some clarification on what you are trying to do exactly.
I'm working on a term paper that performs operations with complex numbers. Application looks like this:
If you click on "Calculate", will calculate the operands and the result is displayed in a new dialog box. So I have two dialogs - a main window (up on pic) to display the read result (down on pic). Unfortunately I was not able to save result in the main dialog box, which is then written to a text file. There is important piece of code:
Thank you for ideas.
In your MainForm class declare a property as
public class MainForm:Form
{
public string CalculationResult { get; set; }
...
...
//Your code here
...
...
}
then on method of calculate change it to
if(resultBool!=null)
{
CalculationResult = resultBool.ToString());
formResult dlg=new formResult(CalculationResult);
dlg.Owner=this
dlg.StartPosition=FormStartPosition.CenterParent;
dlg.ShowDialog();
}
else
{
...
...
//your code
...
...
}
and change the following line
sw.WriteLine("Result: ");
to
sw.WriteLine("Result: " + CalculationResult);
in saveData method which is in MainForm class. Hope this will work for you. Happy coding
You have to use a reference on the target form to write on it.
You have to assure that you use the correct targetForm reference. You could either create a new targetForm or use an existing one. You could for example use the "parent" form of your dialog box and set the text of the main form textbox, from a dialog box event (using this as MSDN reference):
Dim targetForm As Form = Me.parentForm
targetForm.targetTextBox.Text = "text"
Hope I helped!
In formResult create a variable which keep a reference of Main form
private MyMainForm _mainForm;
Then create one more constructor which take reference of your Main form as parameter:
public formResult(MyMainForm mainform)
{
this.InitializeComponent();
this._mainForm = mainform;
//Now you have access to public property ResultOut
this.textBoxResult.Text = this._mainForm.ResultOut;
}
After this you can use all public properties and method of your main form in second form(formResult)
I'm developing a WPF C# application and I have a strange behaviour in modification of objects. I try to explain it in general way.
Suppose that you have an object of a class described as follows:
public class A
{
int one;
bool two;
List<B> listofBObjects;
}
where B is:
public class B
{
int three;
int four;
}
I pass an instance of A class and an instance of B class from a window to another, only defining two variables of type A and B in the second window and passing them before the Show() method, with the following code, executed into an instance of window FirstWindow:
SecondWindow newWindow = new SecondWindow();
newWindow.instanceOfA = this.instanceOfA; //instanceOfA is of type A
newWindow.instanceOfB = this.instanceOfA.listOfBObjects[0]; //instanceOfB is of type B
newWindow.Show();
If I have to repeat this code twice(that is, opening twice the window), in the first execution everything works as expected, infact if I modify values in instanceOfB variable, I see the modification also in instanceOfA variable. But, in the second execution, the modification in instanceOfB does not affect instanceOfA...
The modifications are done in newWindow. For example:
this.instanceOfB.three++;
this.instanceOfB.four--;
Imagine that you are in the FirstWindow. Click on a button and SecondWindow opens, passing both variables as described above. In SecondWindow, do some modifications, click on OK and SecondWindow closes, returning control to FirstWindow. If I reclick on the same button, I reopen SecondWindow. If I do modifications now, they do not affect both variables.
I try to have a look (in VS2012) at both variables in the console with control expression and I see that, in the first pass of code, both variables changes when code above is executed but, in the second pass of code, only instanceOfB changes...
EDIT:
Following the code that I use to pass parameters to SecondWindow...types are explaind below
IntermediatePosition obj = ((FrameworkElement)sender).DataContext as IntermediatePosition; //IntermediatePosition is Class B
IntermediatePositionsSettingsWindow ips = new IntermediatePositionsSettingsWindow();
ips.currentIntermediatePosition = obj;//this is the instanceOfB
ips.idxOfIpToModify = obj.index;
ips.currentSingleProperty = this.currentPropertyToShow; //this is the instanceOfA object
ips.sideIndex = this.sideIndex;
ips.ShowDialog();
Consider that obj is given by a button selection into a datagrid, in which each row represents an IntermediatePosition object. In the datagrid, there is a column button and, clicking by buttons, IntermediatePositionsSettingsWindow is opened with the proper data
EDIT:
I've performed the folloqing check:
this.currentPropertyToShow.sides[this.sideIndex].intermediatePositionList[i].GetHashCode() == obj.GetHashCode()
where i is the index of related IntermediatePosition object. At first usage of IntermediatePositionsSettingsWindow the objects result equals, but in second usage they are different
Why this thing happens?
If it is needed any other clarification, I will edit the question
Thanks
It's difficult to give a proper answer to this, as there is insufficient code to correctly work out the issue. However, if you are databinding, then I believe you need to implement this interface. It is possible that you're issue is simply that you're model is not reflecting the changes to the screen.
I can't reproduce your problem. Here's a simplified representation of your class relation (as I understood from your question). Please let us know if this is correct:
public partial class MainWindow : Window
{
internal A instanceOfA;
internal B instanceOfB;
public MainWindow()
{
InitializeComponent();
instanceOfB = new B() { };
instanceOfA = new A() { listOfBObjects = new List<B>() { instanceOfB } };
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SecondWindow newWindow = new SecondWindow();
newWindow.instanceOfA = this.instanceOfA; //instanceOfA is of type A
newWindow.instanceOfB = this.instanceOfA.listOfBObjects[0]; //instanceOfB is of type B
newWindow.Show();
}
}
public partial class SecondWindow : Window
{
internal A instanceOfA;
internal B instanceOfB;
public SecondWindow()
{
InitializeComponent();
Loaded += SecondWindow_Loaded;
}
void SecondWindow_Loaded(object sender, RoutedEventArgs e)
{
MessageBox
.Show(String.Format("{0}",
this.instanceOfB == this.instanceOfA.listOfBObjects[0]));
this.instanceOfB.three++;
this.instanceOfB.four--;
}
}
Note: this is not an answer, just trying to establish some common ground for further discussions, as comments don't leave you enough freedom for code samples.
Thanks to #pm_2 and #BillZhang comments, I found a row in my code in which this.currentPropertyToShowwas edited. After the returning back at first window, infact, I perform the refresh of the window, but it is not needed to edit this.currentPropertyToShow, so I have commented it and everything works!
Thanks everybody for precious comments and suggestions!