I add a window class in my WPF project as below:
public partial class ParameterInput : Window
{
public ParameterInput()
{
InitializeComponent();
}
public void show()
{
bool ac= Activate();
}
}
And I do create a object of this class, and I hope it can be activated.
void myTap(object sender, MouseButtonEventArgs e)
{
ParameterInput ParameterInputDialog= new ParameterInput();
ParameterInputDialog.show();
//bool ac = ParameterInputDialog.Activate();
}
But I find this method do not work, the return value (ac) is false. why? Do anybody know how to solve this problem? I just want to open the dialog which I defined.
this is because in Windows Forms and in WPF as well, to show a Window you should call its Show method not just the Activate one, try to call the Show Method instead, see an example here:
How to open second window from first window in wpf?
This question has be solved, please see: https://msdn.microsoft.com/en-us/library/system.windows.window.owner%28v=vs.110%29.aspx.
So I change my code into:
ParameterInput ParameterInputDialog= new ParameterInput();
ParameterInputDialog.Owner = this;
ParameterInputDialog.Show();
And it do works well. Thanks for all your help.
Related
how do I hide an Instance of a Window which was created in an Method, in another Method?
I have a Login Window with a button "Register" and when you click that, the Register-Window is opening, and the Login-Window is hiding (That is working fine).
The Problem now is, i have on the Register-Window a Button "Back" which should hide the Register Window and Show the Login Window.
I Can show the Login Window with : "Application.Current.MainWindow.Show();", but i dont know how to hide the Register-Window. Normally i would just go for "Regis.Hide()", but i can´t do that because i have the instance of Regis in the Method, which opens the Register Window.
I understand, that if i create a second instance in the second Method and hide this, that that wont work because there are 2 seperate instances now.
But as i said, i dont know how i should do this either.
OpenRegistrationGui:
ICommand _RegisterBack;
public void Open()
{
Application.Current.MainWindow.Hide();
Register regis = new Register();
regis.Show();
}
public ICommand RegisBackCommand
{
get
{
if (_RegisterBack == null)
{
_RegisterBack = new RelayCommand(
param => Back()
);
}
return _RegisterBack;
}
}
public void Back()
{
Application.Current.MainWindow.Show();
//I Want to Hide the Regis here, but i cant use the Instance from above.
}
MyViewModel:
OpenRegistrierungsGUI RegisGUI = new OpenRegistrierungsGUI();
public ICommand RegisBack
{
get => RegisGUI.RegisBackCommand;
set => RegisBack = RegisGUI.RegisBackCommand;
}
The Same Thing is with the Open() Method.
The Result i want is simply that the Register Window is hiding and the Login Window shows off.
This will resolve your issue by making regis a member variable that the whole class has access to...
private Register regis;
public void Open()
{
Application.Current.MainWindow.Hide();
// Create the register window, if it doesn't exist
if (regis == null)
{
regis = new Register();
}
regis.Show();
}
public void Back()
{
// hide the register window, if it exists
if (regis != null)
{
regis.Hide();
}
Application.Current.MainWindow.Show();
}
There are different ways of doing this, but this one ensures only one instance of the register window and gives you the show/hide ability you need.
simply use regis.hide(); hopefully its work for you.
private Register regis;
public void Back()
{
Application.Current.MainWindow.Show();
regis.hide();
}
here you want to use one function variable into another
Declare regis globally than initialize it in method where you first you use it .
In this way there will be only one instance of regis .
Now you can do
regis.Hide()
or
regis.Show()
in any method of your class
I found the solution:
I fired the Open() Method (Which worked perfectly).
When I wanted to fire the Back() Method I accidentally created an Instance of "OpenRegistrationGui" and tried to Close it, which it obviousely can´t, because its another Instance.
I made the Property "RegisBackCommand" Static and fired it now directly from the ViewModel, which works now.
Anyway... Thank you all for your fast Answers and help!!!
I have a C# application that allows the user to log certain events that occur in a game. For simplicity I'll call them ParentForm and ChildForm.
ParentForm is used 99% of the time, to log common events. This is represented as the user clicking a PictureBox and the Tag property of that PictureBox being added to a ListBox. When a "rare" event occurs, the user can click a "log rare event" button on ParentForm to open ChildForm which opens a set of "rare event" PictureBoxes, which function the same as in the ParentForm. The challenge is that I want these common and rare events to be logged to the same ListBox, so I am trying to find out how I would get a PictureBox click (and subsequent Tag from this PictureBox) on the ChildForm to the ListBox on the ParentForm.
The ParentForm does not close while ChildForm is open, and needs to stay open.
In the ParentForm code, I already have the code needed to capture one of the PictureBox clicks and grabbing the Tag, as well as handling dealing with adding it to the ListBox, so it'd be nice if I could just use these.
Here's what I've tried so far for the Parent:
// This file is EventLogger.cs
using rareEvent;
namespace mainWindow {
public partial class EventLogger : Form {
// In the ParentForm (listeners for PictureBox clicks are handled elsewhere)
public void pictureBox_Click(object sender, EventArgs e) {
PictureBox pbSender = (PictureBox) sender;
// Open new window and handle "rare" drops
if (pbSender.Tag.ToString() == "rare") {
// Open rare form
EventLogger.RareForm rare = new EventLogger.RareForm();
rare.Show();
}
}
}
}
and here's the child:
// This file is Rare.cs
using EventLogger;
namespace rareEvent {
public partial class rareEventForm : Form {
// In the ChildForm
private void pictureBox_Click(object sender, EventArgs e) {
// Does not compile if form is not instantiated, but I do not
// want a new instance
EventLogger form;
form.pictureBox_Click(sender, e);
}
}
}
I figured something like this would work, but it gives the error
The type or namespace name 'EventLogger' does not exist in the namespace
'mainWindow' (are you missing an assembly reference?)
Any help would be much appreciated. All the other examples I've found of value passing between forms all seem to create new instances which I don't want or were 8 years old and didn't work.
Appreciate it!
Edit: Code updated to have using <namespace> in each file. The problem still exists of not being able to send values between both forms without using new. (See comment to this answer)
In the first form create an instance (of it) here like my form1. It must be static and all datatypes you want to access should be public.
//FORM1
public partial class Form1 : Form
{
//Instance of this form
public static Form1 instance;
//For testing
public string myProperty = "TEST";
//Assign instance to this either in the constructor on on load like this
public Form1()
{
InitializeComponent();
instance = this;
}
//or
private void Form1_Load(object sender, EventArgs e)
{
//Assign the instance to this class
instance = this;
}
Then in form2 when calling EventLogger.RareForm rare = new EventLogger.RareForm(); instead of new form do
EventLogger.RareForm rare = EventLogger.RareForm.instance
Or in my case
Form1 frm = Form1.instance;
I then check the property of form 1 FROM form2 like so
Console.WriteLine(frm.myProperty);
Output was "Test"
Any trouble shout.
C# windows forms:
Is it possible to create a button that changes the text of a ToolStripMenuItem in another form that is already open?
Something like:
private void button1_Click_1(object sender, EventArgs e)
{
Form1.ToolStripMenuItem.Text = "Some_text";
}
Yes, if the menu created by the form designer the control will be private so you can create a public method or property in the form containing the menu to change the text and call it from the other form.
public void ChangeText(string Text){
this.ToolStripMenuItem.Text = Text;
}
and then call it from outside
Alternately, modify the Form1 designer code so that the private variable for ToolStripMenuItem is public rather than private.
Just had a similar issue, here is my code:
public void UpdateStatusBarUp(string status)
{
if (this.InvokeRequired)
{
this.BeginInvoke((MethodInvoker)delegate
{
UpdateStatusBarUp(status);
});
}
else
{
toolStripStatusLabelUp.Text = status;
statusStripUp.Refresh();
}
}
please bear in mind the Refresh() that needed to actually make the change show up in the GUI.
I get an error trying to send a string from one window to another in my wpf application:
Unable to cast object of type 'WpfApplication4.LoginWindow' to type 'WpfApplication4.MainWindow'.
In my login window the error is on this line:
((MainWindow)Application.Current.MainWindow).StudentID = UserAuthenticationID;
In my main window I have this to test:
public string StudentId { get; set; }
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
label1.Content = StudentID;
}
What am I doing wrong?
EDIT:
No answer has made sense so far, which will be due to my obscure question, I created a wpf application and I have two windows MainWindow.xaml and LoginWindow.xaml.
I want to pass a string (student id) from the login window to the main window after authentication.
I thought the above method was how to do it, as I read it: ((MainWindow)Application.Current.MainWindow).StudentID says where I am intending the string UserAuthenticationID to be sent to?
Then in the MainWindow.xaml I get the string UserAuthenticationID and set it, I then assign a labels content to this public string?
Presumably you create your login window from your main window. If you need to reference your main window from your login window then pass a main window reference to your login window when you construct it. Eg
void MainWindow_Loaded(object sender, RoutedEventArgs e) {
LoginWindow login = new LoginWindow(this);
login.ShowDialog();
}
class LoginWindow : Window {
MainWindow app_window;
public LoginWindow(MainWindow app_window) {
Owner = app_window;
this->app_window = app_window;
}
}
Error coming because its trying to convert Application.Current.MainWindow to MainWindow, which is infact LoginWindow.
suggestion when you are coverting one object other made check before it
if(Application.Current.MainWindow is MainWindow)
{
/// than do the code
}
It looks like your trying to feed the UserAuthenticationID from your login dialog back to your main window where you store it as StudentId.
Why not handle that back in the main window Eg:
if (login.ShowDialog())
StudentId = login.UserAuthenticationID;
It seems that your Application.Current.MainWindow is of Type LoginWindow. But you want to cast it to MainWindow. Both derive (maybe) from Window. But you can't cast a derived class to another derived class.
//Edit
try
((LoginWindow)Application.Current.MainWindow)
or change your Application.Current.MainWindow to a object of type MainWindow
//Edit 2
I think i understood what your intention was. You could try the following:
In your LoginWindow where you press the Button "Login" handle the Buttonevent (Click), get the ID whereever it comes (TextBox) from, put it in a new instance of MainWindow and set the
Application.Current.MainWindow
to the new instance of MainWindow. If I'm wrong on how you will do it, you should give more facts.
Other solution is the LoginDialog solution from Ricibob.
You need to restructure the design of your program. What you want to do isn't terribly hard; you're essentially asking for a good way to communicate between forms.
First off, I suggest not using Application.Current.MainWindow unless you're really sure you need to. You can get apps to work using it, but it's not good design and leads to problems.
We'll start off with the definition of some OtherWindow that will be the popup.
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for OtherWindow.xaml
/// </summary>
public partial class OtherWindow : Window
{
public OtherWindow()
{
InitializeComponent();
}
public string SomeData
{
get
{
//you'll probably want to return the value of a textbox or something else
//the user fills in.
return "Hello World!";
}
}
}
}
From a communication point of view, all that's really important is that it has a property (or properties) with the information that the main form will need to access. Obviously I've omitted all of the code for actually collecting the data to return and instead hard code a value for this example.
Now for the mainform. (All I've added is a button and a label.)
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
OtherWindow other = new OtherWindow();
other.Closed += (sender2, e2) =>
{
label1.Content = other.SomeData;
};
//either of the methods below, depending on desired behavior.
other.Show();
//other.ShowDialog();
}
}
}
While there are quite a lot of ways of making different windows/forms communicate, this is my favorite. All of the logic for the interaction between the windows is in once place (the button click event). The main form clearly "owns" OtherWindow, and OtheWindow doesn't need to know a thing about MainWindow, it only need to know how to collect some information. MainWindow will take care of pulling out the information that it needs.
The code for the button click even reads just like what you want it to do: create a new window, when it's closed, set its content to my label, and show the form. It's all in once place, and in the order that I logically think through it (you can attach the event handler after Show if you want).
Oh, and this is exactly the same way that I would do this in a winforms app too, in case anyone cares, barring the fact that some of the class/property names will be different.
In Visual C# when I click a button, I want to load another form. But before that form loads, I want to fill the textboxes with some text. I tried to put some commands to do this before showing the form, but I get an error saying the textbox is inaccessible due to its protection level.
How can I set the textbox in a form before I show it?
private void button2_Click(object sender, EventArgs e)
{
fixgame changeCards = new fixgame();
changeCards.p1c1val.text = "3";
changeCards.Show();
}
When you create the new form in the button click event handler, you instantiate a new form object and then call its show method.
Once you have the form object you can also call any other methods or properties that are present on that class, including a property that sets the value of the textbox.
So, the code below adds a property to the Form2 class that sets your textbox (where textbox1 is the name of your textbox). I prefer this method method over making the TextBox itself visible by modifying its access modifier because it gives you better encapsulation, ensuring you have control over how the textbox is used.
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public string TextBoxValue
{
get { return textBox1.Text;}
set { textBox1.Text = value;}
}
}
And in the button click event of the first form you can just have code like:
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.TextBoxValue = "SomeValue";
form2.Show();
}
You can set "Modifiers" property of TextBox control to "Public"
Try this.. :)
Form1 f1 = (Form1)Application.OpenForms["Form1"];
TextBox tb = (TextBox)f1.Controls["TextBox1"];
tb.Text = "Value";
I know this was long time ago, but seems to be a pretty popular subject with many duplicate questions. Now I had a similar situation where I had a class that was called from other classes with many separate threads and I had to update one specific form from all these other threads. So creating a delegate event handler was the answer.
The solution that worked for me:
I created an event in the class I wanted to do the update on another form. (First of course I instantiated the form (called SubAsstToolTipWindow) in the class.)
Then I used this event (ToolTipShow) to create an event handler on the form I wanted to update the label on. Worked like a charm.
I used this description to devise my own code below in the class that does the update:
public static class SubAsstToolTip
{
private static SubAsstToolTipWindow ttip = new SubAsstToolTipWindow();
public delegate void ToolTipShowEventHandler();
public static event ToolTipShowEventHandler ToolTipShow;
public static void Show()
{
// This is a static boolean that I set here but is accessible from the form.
Vars.MyToolTipIsOn = true;
if (ToolTipShow != null)
{
ToolTipShow();
}
}
public static void Hide()
{
// This is a static boolean that I set here but is accessible from the form.
Vars.MyToolTipIsOn = false;
if (ToolTipShow != null)
{
ToolTipShow();
}
}
}
Then the code in my form that was updated:
public partial class SubAsstToolTipWindow : Form
{
public SubAsstToolTipWindow()
{
InitializeComponent();
// Right after initializing create the event handler that
// traps the event in the class
SubAsstToolTip.ToolTipShow += SubAsstToolTip_ToolTipShow;
}
private void SubAsstToolTip_ToolTipShow()
{
if (Vars.MyToolTipIsOn) // This boolean is a static one that I set in the other class.
{
// Call other private method on the form or do whatever
ShowToolTip(Vars.MyToolTipText, Vars.MyToolTipX, Vars.MyToolTipY);
}
else
{
HideToolTip();
}
}
I hope this helps many of you still running into the same situation.
In the designer code-behind file simply change the declaration of the text box from the default:
private System.Windows.Forms.TextBox textBox1;
to:
protected System.Windows.Forms.TextBox textBox1;
The protected keyword is a member access modifier. A protected member is accessible from within the class in which it is declared, and from within any class derived from the class that declared this member (for more info, see this link).
I also had the same doubt, So I searched on internet and found a good way to pass variable values in between forms in C#, It is simple that I expected. It is nothing, but to assign a variable in the first Form and you can access that variable from any form. I have created a video tutorial on 'How to pass values to a form'
Go to the below link to see the Video Tutorial.
Passing Textbox Text to another form in Visual C#
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
TextBox txt = (TextBox)frm.Controls.Find("p1c1val", true)[0];
txt.Text = "foo";
}