Why "this" works but "Form.Activeform" throws NullRefernceException? - c#

if this keyword refers to the current instance of the class as instanced in program class(Application.Run(new Form1()))
we can reach it's properties with this keyword
this .Text = "debuggging";
this .Opacity = 54;
this .ShowIcon = true;
this .Size = new Size(100, 100);
why cant ı reach it with Form1.ActiveForm.*(All properties)
just out of curiosity but why
when coded like this
Form1.ActiveForm.Text = "debugla";
Form1.ActiveForm.Opacity = 54;
Form1.ActiveForm.ShowIcon = true;
Form1.ActiveForm.Size = new Size(100, 100);
and activeform must bring us the currently active form used
it throws nullreference exception why ?

MSDN: Form.ActiveForm: "A Form that represents the currently active form, or null if there is no active form."
So maybe because you are debugging the form is not active(has not focus), therefore it returns null.

ActiveForm returns the active form... this means that if your window doesn't have focus, then it is not active. Therefore by using it in this way you greatly risk your program producing an error.
Using this ensures you are accessing the form you are intending to change
You should also note that ActiveForm is a static property and therefore it has no link whatsoever to the form you are using it in if you have any other windows open in your application then your changes could apply to these other dialogs

You can do this:
Form currentForm = Form.ActiveForm;
if(currentForm != null)
{
//use currentForm properties
}
Form.ActiveFormgets the currently active form for this application.
while this refers to current instance of Form1.

Related

ToolStripMenuItem strange behavior on visible property [duplicate]

This question already has an answer here:
How to set a ToolStripMenuItem Visible in code?
(1 answer)
Closed 1 year ago.
I have encounter that issue a long time ago and again now. I cannot figure out what special thing had to be done to edit the ToolStripMenuItem control a Visible property while inside a form load.
in designer.cs
private System.Windows.Forms.ToolStripMenuItem mnuExport;
//
// mnuExport
//
this.mnuExport.Name = "mnuExport";
this.mnuExport.Size = new System.Drawing.Size(116, 22);
this.mnuExport.Text = "Export";
this.mnuExport.Visible = false;
this.mnuExport.Click += new System.EventHandler(this.mnuExport_Click);
in the form code
public partial class MainBuilder : Form
{
private void MainBuilder_Load(object sender, EventArgs e)
{
mnuExport.Visible = true;
}
}
In the code above export is a menu item of type ToolStripMenuItem which trough the property grid in the form design mode I have modified it's Visible property to false. So in the form load I want to switch to the visible state to true. I thought it be easy so I coded all the logic around and it failed. So I decided to remove all my code and simply hardcode the set to true and to my surprise this does not work.
When I put the breakpoint on the line in the form_load I clearly see it's false and if it let the line run the value is still false.
I recall seeing this issue in the past but cannot find anything about it. I also tried with 4-5 other menu item in that window and they all show the same behavior.
EDIT
just tried to put visible = true in the designer.cs instead and in the form_load still tells me the value is false. There is some major issues here.
As mentioned in the comments the property Visible getter does not reflect the actual inner property value until later in the lifecycle. It is still unavailable in the form_loaded event. My main problem is that one menu visibility state was based on if all sub menus are not visible then it should not either. To do so I was iterating on it's child and checking the Visible property. The problem is them having Visible to false due to the way it works the parent set it's own Visible to false as well.
I don't like the solution but that's the only way to make it work
// get all sub menus
var subMenus = mnuExport.DropDownItems.Cast<ToolStripItem>().ToList();
// create a list of bool that will store the visible state I want the controls to have. put them to true by default
var menusVisibleStates = Enumerable.Repeat(true, menus.Count).ToList();
// set the visibility state of each sub menus
for (int i = 0; i < menus.Count; i++)
{
// some logic is here that choose true or false but is irrelevant here
var visibleStateIWant = true;
// set the visible state stored
menusVisibleStates[i] = false;
// set the actual control value that will change later on
menus[i].Visible = false;
}
/// now here I use the state I have specified and NOT the menu object property
mnuExport.Visible = menusVisibleStates.Any(o => o);

WinForms MDI inherid form has different propertie values in parent?

I am doing some maintenance on a legacy winforms application.
The project uses form inheritance which makes my job much easier, but there is a strange problem. The setup is as follows:
FormBase : Form
FormBaseList : FormBase
FormClientList : FormBaseList
The problem I have now is with the property WindowsState.
I create a new FormClientList.
FormClientList f = new FormClientList();
f.MdiParent = this;
f.show();
Than I click on the maximize button so it becomes maximized.
Now I have a button (for debug purpose) on FormClientList to show me the value of the property WindowState and it returns maximized, as I expected.
In FormBaseList there is some code that needs to know the value of this property, but here it always returns normal, not maximized.
The code is on the doubleclick of a datagridview, which will create another form.
// code in FormBaseList
FormDetail detailForm = new FormDetail();
detailForm.MDIParent = this.MDIParent;
detailForm.Show();
if (this.WindowState == FormWindowState.Normal) // this = the maximized instance of FormClientList
{
// why do I get here when FormClientList is maximized ??
detailForm.Left = this.Left + 20;
detailForm.Top = this.Top + 20;
}
So it seems that the instance of this form has different values for this propertie depending from which class I run my testcode ?
How do I fix this ?

Invalid printer exception

I have following code in a printing dialog in a windows form.
myPrintDialog = new PrintDialog();
System.Drawing.Bitmap memoryImage = new System.Drawing.Bitmap(pnVTCard.Width, pnVTCard.Height);
pnVTCard.DrawToBitmap(memoryImage, pnVTCard.ClientRectangle);
if (myPrintDialog.ShowDialog() == DialogResult.OK)
{
System.Drawing.Printing.PrinterSettings values;
values = myPrintDialog.PrinterSettings;
myPrintDialog.Document = printDocument1;
printDocument1.PrintController = new StandardPrintController();
printDocument1.Print();//This line shows system.drawing invalid printer exception when i hover over the code.
saveToVC(Convert.ToInt32(cmbVID.SelectedItem.ToString()), cmbElectionName.SelectedItem.ToString());
}
printDocument1.Dispose();
public System.Drawing.Printing.PrintDocument printDocument1 { get; set; }
when I try to handle the exception it shows null reference. Can someone kindly show what to correct.
As I don't know much about this can some one explain me what the wrong I'm doing here.?
pnVTcard is a panel control
Make sure you use references which are set to an instance of an object (sounds familiar? :) )
Maybe you are not setting printDocument1 before accessing its properties. Or maybe some other object, like those cmb... SelectedItem.
If you still can't pinpoint the culprit, go ahead and use break points and manually inspect the references.

Awesomium WebControl trouble with Enable Control in Winform c#

I would use this Browser Framework in my Winform Application c#.
I just Saw the Documentation HERE
So i would use this Method
I just create a new Class and a new Awesomium.Windows.Forms.WebControl Object.
Now if i use it without any particulary method (just the ones to create object and Load the Url Source it works. But when i want use This method :
browser.SetHeaderDefinition("MyHeader", myCol); //myCol is a NameValueCollection
i recive this error The control is disabled either manually or it has been destroyed.
On the first page that i linked there is wrote :
In addition to its regular meaning, the Enabled property has a special meaning in WebControl: it also indicates if the underlying view is valid and enabled.
A WebControl is considered invalid when it has been destroyed (by either calling Close() or Shutdown()) or was never properly instantiated.
Manually setting the Enabled property to true, will temporarily render the control disabled.
....
....
While disabled (either because the view is destroyed or because you manually set this property) attempting to access members of this control, may cause a InvalidOperationException (see the documentation of each member).
Now i tried to play with the ENABLED property but i still get this error. What i have to do to resolve this problem? I really didn't understand.
Awesomium.Windows.Forms.WebControl browser =
new Awesomium.Windows.Forms.WebControl();
this.SuspendLayout();
browser.Location = new System.Drawing.Point(1, 12);
browser.Name = "webControl1";
browser.Size = new System.Drawing.Size(624, 442);
browser.Source = new System.Uri("http://www.google.it", System.UriKind.Absolute);
browser.TabIndex = 0;
**** This below is the code that i cant use cause i get the error control
// System.Collections.Specialized.NameValueCollection myCol =
// new System.Collections.Specialized.NameValueCollection();
// myCol.Add("Referer", "http://www.yahoo.com");
// browser.SetHeaderDefinition("MyHeader", myCol);
// browser.AddHeaderRewriteRule("http://*", "MyHeader");
The issue is that you cannot set the header definition until the control has finished being created. You just need to delay when you're setting the header definition until the control is ready. I'm not a Winforms expert, so there may be a better event to use to determine where a control is in its lifecycle, but here's a working modification of what you posted that just uses the control's Paint event to defer the problematic method calls:
public partial class Form1 : Form
{
private Awesomium.Windows.Forms.WebControl browser;
public Form1()
{
InitializeComponent();
browser = new Awesomium.Windows.Forms.WebControl();
//delay until control is ready
browser.Paint += browser_Paint;
Controls.Add(browser);
browser.Location = new System.Drawing.Point(1, 12);
browser.Name = "webControl1";
browser.Size = new System.Drawing.Size(624, 442);
browser.Source = new System.Uri("http://www.google.it", System.UriKind.Absolute);
browser.TabIndex = 0;
}
void browser_Paint(object sender, PaintEventArgs e)
{
browser.Paint -= browser_Paint;
System.Collections.Specialized.NameValueCollection myCol =
new System.Collections.Specialized.NameValueCollection();
myCol.Add("Referer", "http://www.yahoo.com");
browser.SetHeaderDefinition("MyHeader", myCol);
browser.AddHeaderRewriteRule("http://*", "MyHeader");
}
}

Sharing a variable between two winforms

I have a winforms application.
I have a textbox on one form (call F1) and when a button is clicked on this form (call F2), it launches another form.
On F2, I want to set a string via a textbox (and save it to a variable in the class), and then when I close this form, the string will appear in a label in F1.
So I am basically sharing variables between both forms. However, I can't get this to work correctly. How would this code look?
I would add a new property to form2. Say it's for a phone number. Then I'd add a friend property m_phone() as string to form 2. After showing an instance of form2 but before closing it, you can refer to the property m_phone in form1's code.
It's an additional level of indirection from Matthew Abbott's solution. It doesn't expose form2 UI controls to form1.
EDIT
e.g.:
public string StoredText
{
get;
private set;
}
inside the set you can refer to your UI control, like return textBox1.text. Use the get to set the textbox value from an earlier load.
And:
public string GetSomeValue()
{
var form = new F2();
form.ShowDialog();
return form.StoredText;
}
Just ensure that StoredText is populated (or not, if appropriate) before the form is closed.
Are you showing the second form as a dialog, this is probably the best way to do it. If you can avoid doing shared variables, you could do the following:
public string GetSomeValue()
{
var form = new F2();
form.ShowDialog();
return form.TextBox1.Text;
}
And called in code:
Label1.Text = GetSomeValue();
This might not be the most efficient way of approaching, but you could create a class called DB (database). Inside this class, create variables like
public static bool test or public static bool[] test = new bool[5];
In your other forms, you can just create an instance. DB db = new DB(); then grab the information using db.test = true/false. This is what I've been doing and it works great.
Sorry, I'm only like a year late.

Categories