So i have two Windows.
The first window stores all the data with textboxes, comboboxes etc.
In the second window i want to the user to enter some Information and based on the Information i want to Change something in the mainwindow.
I changed
public partial class Window2 : Window
to
public partial class Window2 : MainWindow
but it still does not work.
public partial class MainWindow : Window
{
int Languagetoken = 1;
public MainWindow()
{
InitializeComponent();
DateTextBox.Text = DateTime.Now.ToShortDateString();
}
...
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
}
{
Do not know how to do it. The code above is not in the same xaml they just Show the initialization of both.
There are several ways to solve this but the simplest one in your case is probably to inject Window2 with a reference to the MainWindow when you create it:
Window2 win = new Window2(this);
Window2:
public partial class Window2 : Window
{
private readonly MainWindow _mainWindow;
public Window2(MainWindow mainWindow)
{
_mainWindow = mainWindow;
InitializeComponent();
}
...
}
You could then access any internal or public member of the MainWindow in Window2 using the _mainWindow reference, e.g.:
_mainWindow.textBlock1.Text = "...";
By default text boxes and all other controls are represented by private member variables int he class representing your form so you won't be able to reach into it.
In order access it from outside, you can add a property inside the first window...
public string DataText
{
get
{
return DataTextBox.Text;
}
set
{
DataTextBox.Text = value;
}
}
Or you can change the access level of the controls to internal or public so that you can access it by using a reference to the window.
Related
I'm trying to add a few extra base properties (somewhere) in my project so that every window I create will automatically inherit these properties.
E.g. each window will have a "block_count" based on the area of the window
For context, I'm using a WPF project.
Currently trying: I've created an abstract window class with my desired properties and then defined my MainWindow as one of these types to inherit the property and method...
But when coding in my MainWindow class I still can't access the property or method even though it should have inherited them? Where am I going wrong or what is the best way to add properties to all windows in my project?
My Abstract Window class
public abstract partial class AbWinDefiner : Window
{
private int _block_count;
private void get_block_count()
{
_block_count = Convert.ToInt32(Math.Floor(Width * Height / 32));
}
public AbWinDefiner()
{
InitializeComponent();
}
}
My Main Window class
public partial class MainWindow : AbWinDefiner
{
public MainWindow()
{
InitializeComponent();
}
}
Make it protected, not private
I have a problem, after adding this code so I can access my MainWindow controls in Downloader class:
public partial class MainWindow : Form
{
private Downloader fileDownloader;
public MainWindow()
{
InitializeComponent();
fileDownloader = new Downloader(this);
}
//smth
}
and
class Downloader : MainWindow
{
private MainWindow _controlsRef;
public Downloader(MainWindow _controlsRef)
{
this._controlsRef = _controlsRef;
}
// smth
}
it now gives me "An unhandled exception of type 'System.StackOverflowException' occurred in System.Windows.Forms.dll" on line
this.mainControlPanel.ResumeLayout(false);
in MainWindow.Designer.cs. If i comment out the code above, it works fine. Any ideas please?
PS. Also, when I'm in Downloader class, should i access the controls like
textbox.Text
or
_controlsRef.textbox.Text
Both seem to give no compile errors, is there any difference between the two?
Your Downloader class inherits MainWindow. When you instansiate it, according to the C# specification, the base class is initialized first. When MainWindow initializes, it creates a new instance of Downloader, which causes it eventually to stackoverflow, because you're in an endless cyclic dependency.
Since Downloader inherits MainWindow, there is no point in getting an instance of it via your constructor. You can simply access it's protected and public members from your derived.
For example:
public partial class MainWindow : Form
{
protected string Bar { get; set; }
public MainWindow()
{
Bar = "bar";
InitializeComponent();
}
}
public class Downloader : MainWindow
{
public void Foo()
{
// Access bar:
Console.WriteLine(Bar);
}
}
It's problem because here you are having cyclic dependancy i.e. both the method waiting for each other to complete.
check
public MainWindow()
{
InitializeComponent();
fileDownloader = new Downloader(this);//this wait to complete downloader intialization
}
public Downloader(MainWindow _controlsRef)//this wait to complete mainwindow first
{
this._controlsRef = _controlsRef;
}
my mean to say as you are inheriting Downloader from MainWindow , which in constructor crating downloader instace...and downloader calls Mainwindow constructor first as its parent crates problem for you here
Solution
if want reference you can do like this
public partial class MainWindow : Form
{
protected MainWindow mainWindow;
public MainWindow()
{
InitializeComponent();
mainWindow = this;
}
//smth
}
class Downloader : MainWindow
{
public Downloader()
{
//this.mainWindow //will give you reference to main winsow
}
// smth
}
In WPF application it is easy to access MainWindow content but how to do in usercontrol.
In WPF Application, if my MainWindow name is Window1 and i have to access its one of the string variable named CName from some other class in same application.
Window1 ww = Application.Current.MainWindow as Window1;
String reqstring = ww.CName ;
I want to do same thing in usecontrol too.
Assume my usercontrol name is ABCcontrol and first/main Class name is ABCconrolLib
namespace ABCcontrol
{
public partial class ABCcontrolLib : UserControl
{
Public String CName = "ABC";
//....
}
}
Now i want to access this CName in some other class of same usercontrol by using Application.Control.MainWindow or by some other similar way
Please help me out as this is my first UserControl in WPF
You can access Application.Current.MainWindow because you have just one instance of MainWindow in your whole application so they defined it as a static property.
If you have the same characteristic for your users control (just you need to use a single instance of it in the whole application) you can define a static property there as well.
Something like :
then you can access name property like UserControl1.Instance.CName
public partial class UserControl1 : UserControl
{
public static UserControl1 Instance
{
get;
private set;
}
Public String CName = "ABC";
public UserControl1()
{
if (Instance != null)// there should be just one instance
throw new NotSupportedException();
Instance = this;
InitializeComponent();
}
}
if you get error then you do not have just one instance of your usercontrol, you have to define a List and register each instance of your users controls there. Something like:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
(App.Current as App).UserControl1List.Add(this);
InitializeComponent();
}
}
public partial class App : Application
{
public App()
{
UserControl1List = new List<UserControl1>();
}
public List<UserControl1> UserControl1List
{
get;
private set;
}
}
then you can reach to each instance like (App.Current as App).UserControl1List[0]...
or you can use a dictionary for storing each UserControl there.
I have a main form with a tab control on it. The tabs get populated by adding panels from other forms within the solution. One of these panels has some code that will pop up an options window. I want that window to align itself to the top right hand side of the main form. To do this I need the location and size of the main form. However, I cannot seem to access any property that will tell one of the panels what the location of that main form is.
I've tried things like this.Parent, this.ParentForm and this.GetContainerControl(). They all return null.
Any ideas?
Addendum
//Code for the main form:
namespace WinAlignTest {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
tabControl1.TabPages[0].Controls.Add(new SomeApplication().panel1);
}
}
}
//Code that shows the option window
namespace WinAlignTest {
public partial class SomeApplication : Form {
private ApplicationOptions Options;
public SomeApplication() {
InitializeComponent();
Options = new ApplicationOptions();
}
private void button1_Click(object sender, EventArgs e) {
Options.Show();
//This will always move the location to {0,0}
Options.Location = new Point(base.Location.X,base.Location.Y);
}
}
}
I'm confused, you seem to be adding a panel which belongs to SomeApplication to Form1. I would suggest you actually make SomeApplication a UserControl instead of a form:
//Code for the main form:
namespace WinAlignTest {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
tabControl1.TabPages[0].Controls.Add(new SomeApplication());
}
}
}
//Code that shows the option window
namespace WinAlignTest {
public partial class SomeApplication : UserControl {
private ApplicationOptions Options;
public SomeApplication() {
InitializeComponent();
Options = new ApplicationOptions();
}
private void button1_Click(object sender, EventArgs e) {
Options.Show();
// You might need to use PointToScreen here
Options.Location = this.Location;
}
}
}
Check out
Application.OpenForms
That should give you access to what you want.
the base identifier accesses a parent element.
Two possible problems: First, your constructors don't explicitly extend your base constructor. it would look like this:
public Form1():base(){}
I still recommend making getter methods in the Form1 class. It would look something like this:
public int Form1Location
{
get{return /*FormLocation*/}
}
and call it from WinAlignTest
Let me know if this works.
This is my MDI Parent.
public partial class frmMain : Form
{
public Options options {get; set;}
public Project project {get; set;}
public frmMain()
{
InitializeComponent();
}
}
My MDI child below need to access the project and option.
public partial class frmInput : form
{
public frmInput(frmMain parent)
{
InitializeComponent();
this.MdiParent = parent;
//Of course I can do this
Options options = ((frmMain) this.MdiParent).options;
//But if I can have something as following, I can have
//a static method to access options in the frmMain anywhere.
frmMain mainform = Application.MainForm;
Options options = mainform.options;
}
}
If Application doesn't provide the access to the MdiParent, any other means that we can access it through static method?
Why don't you manually create a static field to do so? Something like:
public class frmMain {
public static frmMain ApplicationMainWindow {get; private set;}
public frmMain() {
ApplicationMainWindow = this;
InitializeComponent();
}
}
Other than that Application.OpenForms returns all open forms for the application and you can look it up to find the frmMain instance. It's a less than ideal solution though.
This would work fine:
public partial class frmInput : form
{
private frmMain mainFrame;
public frmInput(frmMain parent)
{
mainFrame = parent;
InitializeComponent();
this.MdiParent = parent;
//Of course I can do this
Options options = mainFrame.options;
}
private void Something() {
Options o = mainFrame.options; //can access options now.
}
}
There's maybe more OO approaches that could be applied to decomple these classes though.