Main window Textbox acces from class in other file - c#

so I have a main window it has lots of other window instance in it
MainWindow
{
Window1 win1= new Window1();
Window2 win2 = new Window2();
// ....... and so on
private keydownevent( ,key e)
{
if(e.keu==key.return)
{
//some logic here
if(some condition)
{
win1.show();
}
else if(some condition)
{
win2.show()
}
// ....
}
}
}
// and in window1 lets say
Window1
{
foo_class fcl = new foo_class();
click_button()
{
// do some logic
fc1.function in class;
}
}
now textbox content are a barcode and i want to clear textbox in MainWindow when window1 is showed and click_button in window 1 is done
//////////
i have tried
MainWindow win= (MainWindow)Application.Current.MainWindow;
win.txtBlock1.Text = "";
putting in foo_class as well as in button_click but it throws error window1 can not be cast to mainwindow
i also tried
creating a constructor that takes argument as textbox in keydown function as window(texbox) but that willl create a new instance every tim but i want only want on instance created while instantiating mainwindow and keep using that window1 instance
PLease suggest some method that work in clearing textbox in main window ? and where should i put that method

When creating the Windows, you could set the Owner to this. i.e.:
public class MainWindow
{
Window1 win1 = new Window1();
Window2 win2 = new Window2();
...
//in code, before call Show() on win1 or win2
//set win1/win2.Owner = this;
}
Then when you ned to clear the parent you could get a reference to the parent by simply calling ((MainWindow)this.Owner).txtBlock1.Text = "";.
This is all on the assumption that Window1 and Window2 are actually subclasses of Window, or you actually meant to declare win1 and win2 as Window.
EDIT:
As mentioned in the comments, an alternative would be to supply a reference to an instance of MainWindow to the constructors of win1 and win2 if they are subclasses of window via a new constructor.
I'd also recommend that you should create a new method on MainWindow called ClearText so you don't have to expose the text box name.

Related

How to propagate the StateChanged event

I have a child window that has to be on top of another one which is the main.
I don't want to put the child one as TopMost since the user might want to check for data on other windows.
In short the child has to follow that maximize/minimize events as the parent main one
Main minimize--->Child minimize
Main maximize--->Child maximize
To do that I have defined in the main:
this.StateChanged += MainWindow_StateChanged;
and in that
public static event EventHandler OnMainWindowStateChanged;
private void MainWindow_StateChanged(object sender, EventArgs e)
{
OnMainWindowStateChanged?.Invoke(sender,e);
}
The logic should be:
Main window main class ---> Main window engine class ----> child window
To put some names it:
public MainWindow()
{
this.StateChanged += MainWindow_StateChanged;
//call to the engine
m_Designer = new CWorkFlowEditor(this, App.IsDeployment, OnMainWindowStateChanged);
}
...
//In the engine:
public EventHandler OnMainWindowStateChanged;
public CWorkFlowEditor(object parent, bool IsDeployment, EventHandler _OnMainWindowStateChanged)
{
OnMainWindowStateChanged = _OnMainWindowStateChanged;
}
...
// Finally, when I want to create the final child window:
wndPluginConfigurator = new Window() {};
OnMainWindowStateChanged += MainWindow_StateChanged;
wndPluginConfigurator.ShowDialog();
}
private void MainWindow_StateChanged(object sender, EventArgs e)
{
Console.Beep();
}
So the fact is that this event is never called for the above OnMainWindowStateChanged event is always null. And that is for the OnMainWindowStateChanged is also always null.
Obviously if there is a better way to achieve the result and I'd be most grateful for the explanation
Thanks for helping
ADD: The MainWindow is not visible to the CWorkflowEditor. I have therefore tried to pass the EventHAndler with an interface but that didn't work either.
To achieve the following
Main minimize--->Child minimize
Main maximize--->Child maximize
While launching the Child window set the Owner with Main Window.
Means
Window childwindow = new Window
childwindow.Owner = MainWindow
childwindow.Show()
There seems to be some issue passing your eventhandler around, but as the eventhandler is static surely it will be easier to do this instead:
MainWindow.OnMainWindowStateChanged += MainWindow_StateChanged;

C# Specific value passing between forms without new instance

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.

object reference is null

There is one MainWindow and one user-control in my WPF application. I want to call function of my MainWindow in user-control, without creating new instance of MainWindow. For this i made main-window parent of user-control. I wrote this code below for calling function of Parent.
Child User-Control
public partial class AppLogo : UserControl
{
public MainWindow myparent { get; set; }
private void activate_Click_1(object sender, RoutedEventArgs e)
{
myparent.function();
}
. . .
}
Parent Window:
public MainWindow()
{
InitializeComponent();
AppLogo childWindow = new AppLogo();
. . .
Questions:
Is It Possible to create Window a parent of user-control?
If answer of above question is Yes then why it is generating error that Object Reference is Null.
If answer is No it is not possible then how can i achieve this goal. As it is necessary to create user-control in my application as it is requirement.
If you want to have reference in UserControl to MainWindow use following code:
MainWindow mw = Application.Current.MainWindow as MainWindow;
http://msdn.microsoft.com/en-us/library/system.windows.application.mainwindow.aspx
private void activate_Click_1(object sender, RoutedEventArgs e)
{
MainWindow mw = Application.Current.MainWindow as MainWindow;
if(mw != null)
{
mw.function();
}
}
Second solution:
In your code you should set myparent property in MainWindow constructor:
public MainWindow()
{
InitializeComponent();
AppLogo childWindow = new AppLogo();
childWindow.myparent = this;
...
}
In activate_Click_1 event handler the good habit is check if myparent is not null:
private void activate_Click_1(object sender, RoutedEventArgs e)
{
if(myparent != null)
myparent.function();
else
...
}
I'm assuming that the null reference is for the myparent property on AppLogo?
After this line AppLogo childWindow = new AppLogo(); add one saying childWindow.myparent = this;
You may introduce a child parent dependecy as suggested, however since you didn't instantiate MainWindow you should expect a null reference exception when calling myparent.function();
First, you need to instantiate MainWindow, and then set the child parent relationship by calling AppLogo .set_myparent, only then your call won't fail.
You need to pass a reference to the instance of MainWindow as an argument to AppLogo's constructor, then set it to AppLogo's variable for MainWindow.
public AppLogo(MainWindow mainWindow)
{
this.myparent = mainWindow;
}
If you locate your UserControl directly inside your Window, then its Parent property will reference your window.
The exception is called when you try to access the field which contains null value. It contains null because noone placed there anything else. You might want to set it:
AppLogo childWindow = new AppLogo();
childWindow.myparent = <something>;
You just need to recursively search your UserControl's parents until you get an instance of a Window, which will be your goal.
public static Window GetWindow(FrameworkElement element)
{
return (element.Parent as Window) ?? GetWindow(element.Parent);
}

Read input from popup window before executing entire main constructor

I have a wpf application in which I have two wpf windows. One is the main GUI and another is a popup which asks the user to input a number into a text box then press a button.
What I'm wondering is can I somehow call the popup window to be displayed in the main window constructor (this much I have with popup.Show()) and then read the input and wait until the user presses the button to continue on with the rest of the code in the constructor?
Basically once it gets to the popup.Show() line I want it to wait for the user to enter a value and press the button before the rest of the code after popup.Show() in the main window constructor is executed.
Using ShowDialog() instead of Show() will cause the execution to pause until the popup is closed.
Use this:
popup.ShowDialog(); // Execution will halt here until the 'popup' is closed
I personally avoid using custom code inside window constuctor, I usually put this code on Window_Loaded
This should do the trick, but it will not show MainWindow until the Popup is closed.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
protected override void OnInitialized(EventArgs e)
{
var popup = new PopupWindow();
popup.ShowDialog();
base.OnInitialized(e);
}
}
For the Popup
public partial class PopupWindow : Window
{
public PopupWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Close();
}
}

Trying to use a reference to my mainform

Yesterday I asked a question how it is possible to access my mainform from another form to give it the focus.
Giving focus back to main form
The solution was to add a reference to the mainform when the new form is called.
This works great for .focus() by doing:
Form mainform_instance;
public NewForm(Form mainform)
{
this.mainform_instance = mainform;
InitializeComponent();
}
However now I need to access a 'custom function' on the main form from my new form.
But I cannot access it since it is declared as Form mainform_instance and the Form type doesn't have my custom function. (at least that's what I think what goes wrong.)
So I thought I try:
MainForm mainform_instance;
and
Namespace.MainForm mainform_instance;
But both don't work.
How can I access my function (foo()) on the mainform from the new form?
EDIT
As requested by Adam Maras in comment:
namespace Namespace
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
EDIT2
MainForm code which calls the NewForm:
newForm = new Namespace.NewForm(this);
newForm.Show();
NewForm construct:
namespace Namespace
{
public partial class NewForm : Form
{
// here I tried to do MainForm mainform_instance as well as in the construct param
Form mainform_instance;
public NewForm(Form mainform)
{
this.mainform_instance = mainform;
InitializeComponent();
}
In the NewForm objects Load event, this.Owner would return your main form object if you invoked NewForm with a ShowDialog(this) call.
// in your MainForm
NewForm nwForm = new NewForm();
nwForm.ShowDialog(this);
// inside your NewForm object, after loading
(this.Owner as MainForm).Foo();
I realize I misdirected you in your previous post by asking you to use this.Parent(); I should have remembered it is this.Owner(). Apologies!
If you know exactly what kind of form type to use, simply change the code to reference that kind of form.
MainForm mainform_instance;
public NewForm(MainForm mainform)
{
this.mainform_instance = mainform;
InitializeComponent();
}
If you can have multiple types of forms then you can try to cast it to MainForm prior to using it, and if successful - use it.
MainForm mainForm = mainform_instance as MainForm;
if (mainForm != null) mainForm.foo();
Make the custom function public and pass the reference of main form to the new form. Then using the main form's reference you will be able to call any public method of main form from new form
Is your function declared private?
I never recommend a main form reference to any other form ...there is always a better way. That said, if you have a method that needs to be executed from the form, you must pass a reference to that main form method.
public NewForm(Form mainform, Action mainFormMethod)
{
this.mainform_instance = mainform;
InitializeComponent();
mainFormMethod.Invoke(); // or just mainFormMethod();
}
See MSDN: Action Delegate
There is also the Action<T> ...be sure and check those out. If your method requires a return, you will need to check out Func<TResult>
For the records, I would recommend re-thinking sending the reference to the main form.

Categories

Resources