I was wondering if someone could help me with a little issue I'm having. I'm trying to update a textbox from another class but the text is not showing up on in the textbox even though it is being sent as I have printed it to the screen.
The code I'm using is below:
Program.cs
namespace Search
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
try
{
Application.SetCompatibleTextRenderingDefault(false);
}
catch (InvalidOperationException e)
{
}
Application.Run(new Form1());
}
public static readonly Form1 MainLogWindow = new Form1();
}
}
HexToASCII:
public class HexToASCII
{
Output o = new Output();
public void hexToAscii(String hex, int textBox)
{
//Convert the string of HEX to ASCII
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hex.Length; i += 2)
{
string hs = hex.Substring(i, 2);
sb.Append(Convert.ToChar(Convert.ToUInt32(hs, 16)));
}
//Pass the string to be output
string convertedHex = sb.ToString();
Program.MainLogWindow.UpdateTextBox(convertedHex);
}
}
Form1:
private delegate void NameCallBack(string varText);
public void UpdateTextBox(string input)
{
if (InvokeRequired)
{
textBox2.BeginInvoke(new NameCallBack(UpdateTextBox), new object[] { input });
}
else
{
textBox2.Text = textBox2.Text + Environment.NewLine + input;
}
}
I have tried to run it using a new thread ThreadStart ts = delegate()... but I'm unable to get the textbox to update. Sorry I'm very new to c#, could someone please explain the issue so I can understand it and learn for next time. Many thanks :)
This is the problem:
static void Main()
{
...
Application.Run(new Form1());
}
public static readonly Form1 MainLogWindow = new Form1();
You're creating two forms: one of them is being shown (with Application.Run) but you're changing the contents of the text box on the other one:
Program.MainLogWindow.UpdateTextBox(convertedHex);
You haven't shown how you're calling hexToAscii in the first place - personally I would try to avoid having static references to GUI elements like this, but you could get your code to work just by changing your Main method to use:
Application.Run(MainLogWindow);
Related
Consider:
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//int[] val = { 0, 0};
int val;
if (textBox1.Text == "")
{
MessageBox.Show("Input any no");
}
else
{
val = Convert.ToInt32(textBox1.Text);
Thread ot1 = new Thread(new ParameterizedThreadStart(SumData));
ot1.Start(val);
}
}
private static void ReadData(object state)
{
System.Windows.Forms.Application.Run();
}
void setTextboxText(int result)
{
if (this.InvokeRequired)
{
this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result });
}
else
{
SetTextboxTextSafe(result);
}
}
void SetTextboxTextSafe(int result)
{
label1.Text = result.ToString();
}
private static void SumData(object state)
{
int result;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
setTextboxText(result);
}
delegate void IntDelegate(int result);
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
Why is this error occurring?
An object reference is required for the nonstatic field, method, or property 'WindowsApplication1.Form1.setTextboxText(int)
It looks like you are calling a non static member (a property or method, specifically setTextboxText) from a static method (specifically SumData). You will need to either:
Make the called member static also:
static void setTextboxText(int result)
{
// Write static logic for setTextboxText.
// This may require a static singleton instance of Form1.
}
Create an instance of Form1 within the calling method:
private static void SumData(object state)
{
int result = 0;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
Form1 frm1 = new Form1();
frm1.setTextboxText(result);
}
Passing in an instance of Form1 would be an option also.
Make the calling method a non-static instance method (of Form1):
private void SumData(object state)
{
int result = 0;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
setTextboxText(result);
}
More info about this error can be found on MSDN.
For this case, where you want to get a Control of a Form and are receiving this error, then I have a little bypass for you.
Go to your Program.cs and change
Application.Run(new Form1());
to
public static Form1 form1 = new Form1(); // Place this var out of the constructor
Application.Run(form1);
Now you can access a control with
Program.form1.<Your control>
Also: Don't forget to set your Control-Access-Level to Public.
And yes I know, this answer does not fit to the question caller, but it fits to googlers who have this specific issue with controls.
You start a thread which runs the static method SumData. However, SumData calls SetTextboxText which isn't static. Thus you need an instance of your form to call SetTextboxText.
Your method must be static
static void setTextboxText(int result)
{
if (this.InvokeRequired)
{
this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result });
}
else
{
SetTextboxTextSafe(result);
}
}
Credit to #COOLGAMETUBE for tipping me off to what ended up working for me. His idea was good but I had a problem when Application.SetCompatibleTextRenderingDefault was called after the form was already created. So with a little change, this is working for me:
static class Program
{
public static Form1 form1; // = new Form1(); // Place this var out of the constructor
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(form1 = new Form1());
}
}
I actually got this error because I was checking InnerHtml for some content that was generated dynamically - i.e. a control that is runat=server.
To solve this I had to remove the "static" keyword on my method, and it ran fine.
From my looking you give a null value to a textbox and return in a ToString() as it is a static method. You can replace it with Convert.ToString() that can enable null value.
Make the function static. This must solve your problem.
The essence, and solution, to your problem is this:
using System;
namespace myNameSpace
{
class Program
{
private void method()
{
Console.WriteLine("Hello World!");
}
static void Main(string[] args)
{
method();//<-- Compile Time error because an instantiation of the Program class doesnt exist
Program p = new Program();
p.method();//Now it works. (You could also make method() static to get it to work)
}
}
}
Consider:
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//int[] val = { 0, 0};
int val;
if (textBox1.Text == "")
{
MessageBox.Show("Input any no");
}
else
{
val = Convert.ToInt32(textBox1.Text);
Thread ot1 = new Thread(new ParameterizedThreadStart(SumData));
ot1.Start(val);
}
}
private static void ReadData(object state)
{
System.Windows.Forms.Application.Run();
}
void setTextboxText(int result)
{
if (this.InvokeRequired)
{
this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result });
}
else
{
SetTextboxTextSafe(result);
}
}
void SetTextboxTextSafe(int result)
{
label1.Text = result.ToString();
}
private static void SumData(object state)
{
int result;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
setTextboxText(result);
}
delegate void IntDelegate(int result);
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
Why is this error occurring?
An object reference is required for the nonstatic field, method, or property 'WindowsApplication1.Form1.setTextboxText(int)
It looks like you are calling a non static member (a property or method, specifically setTextboxText) from a static method (specifically SumData). You will need to either:
Make the called member static also:
static void setTextboxText(int result)
{
// Write static logic for setTextboxText.
// This may require a static singleton instance of Form1.
}
Create an instance of Form1 within the calling method:
private static void SumData(object state)
{
int result = 0;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
Form1 frm1 = new Form1();
frm1.setTextboxText(result);
}
Passing in an instance of Form1 would be an option also.
Make the calling method a non-static instance method (of Form1):
private void SumData(object state)
{
int result = 0;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
setTextboxText(result);
}
More info about this error can be found on MSDN.
For this case, where you want to get a Control of a Form and are receiving this error, then I have a little bypass for you.
Go to your Program.cs and change
Application.Run(new Form1());
to
public static Form1 form1 = new Form1(); // Place this var out of the constructor
Application.Run(form1);
Now you can access a control with
Program.form1.<Your control>
Also: Don't forget to set your Control-Access-Level to Public.
And yes I know, this answer does not fit to the question caller, but it fits to googlers who have this specific issue with controls.
You start a thread which runs the static method SumData. However, SumData calls SetTextboxText which isn't static. Thus you need an instance of your form to call SetTextboxText.
Your method must be static
static void setTextboxText(int result)
{
if (this.InvokeRequired)
{
this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result });
}
else
{
SetTextboxTextSafe(result);
}
}
Credit to #COOLGAMETUBE for tipping me off to what ended up working for me. His idea was good but I had a problem when Application.SetCompatibleTextRenderingDefault was called after the form was already created. So with a little change, this is working for me:
static class Program
{
public static Form1 form1; // = new Form1(); // Place this var out of the constructor
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(form1 = new Form1());
}
}
I actually got this error because I was checking InnerHtml for some content that was generated dynamically - i.e. a control that is runat=server.
To solve this I had to remove the "static" keyword on my method, and it ran fine.
From my looking you give a null value to a textbox and return in a ToString() as it is a static method. You can replace it with Convert.ToString() that can enable null value.
Make the function static. This must solve your problem.
The essence, and solution, to your problem is this:
using System;
namespace myNameSpace
{
class Program
{
private void method()
{
Console.WriteLine("Hello World!");
}
static void Main(string[] args)
{
method();//<-- Compile Time error because an instantiation of the Program class doesnt exist
Program p = new Program();
p.method();//Now it works. (You could also make method() static to get it to work)
}
}
}
Consider:
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//int[] val = { 0, 0};
int val;
if (textBox1.Text == "")
{
MessageBox.Show("Input any no");
}
else
{
val = Convert.ToInt32(textBox1.Text);
Thread ot1 = new Thread(new ParameterizedThreadStart(SumData));
ot1.Start(val);
}
}
private static void ReadData(object state)
{
System.Windows.Forms.Application.Run();
}
void setTextboxText(int result)
{
if (this.InvokeRequired)
{
this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result });
}
else
{
SetTextboxTextSafe(result);
}
}
void SetTextboxTextSafe(int result)
{
label1.Text = result.ToString();
}
private static void SumData(object state)
{
int result;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
setTextboxText(result);
}
delegate void IntDelegate(int result);
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
Why is this error occurring?
An object reference is required for the nonstatic field, method, or property 'WindowsApplication1.Form1.setTextboxText(int)
It looks like you are calling a non static member (a property or method, specifically setTextboxText) from a static method (specifically SumData). You will need to either:
Make the called member static also:
static void setTextboxText(int result)
{
// Write static logic for setTextboxText.
// This may require a static singleton instance of Form1.
}
Create an instance of Form1 within the calling method:
private static void SumData(object state)
{
int result = 0;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
Form1 frm1 = new Form1();
frm1.setTextboxText(result);
}
Passing in an instance of Form1 would be an option also.
Make the calling method a non-static instance method (of Form1):
private void SumData(object state)
{
int result = 0;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
setTextboxText(result);
}
More info about this error can be found on MSDN.
For this case, where you want to get a Control of a Form and are receiving this error, then I have a little bypass for you.
Go to your Program.cs and change
Application.Run(new Form1());
to
public static Form1 form1 = new Form1(); // Place this var out of the constructor
Application.Run(form1);
Now you can access a control with
Program.form1.<Your control>
Also: Don't forget to set your Control-Access-Level to Public.
And yes I know, this answer does not fit to the question caller, but it fits to googlers who have this specific issue with controls.
You start a thread which runs the static method SumData. However, SumData calls SetTextboxText which isn't static. Thus you need an instance of your form to call SetTextboxText.
Your method must be static
static void setTextboxText(int result)
{
if (this.InvokeRequired)
{
this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result });
}
else
{
SetTextboxTextSafe(result);
}
}
Credit to #COOLGAMETUBE for tipping me off to what ended up working for me. His idea was good but I had a problem when Application.SetCompatibleTextRenderingDefault was called after the form was already created. So with a little change, this is working for me:
static class Program
{
public static Form1 form1; // = new Form1(); // Place this var out of the constructor
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(form1 = new Form1());
}
}
I actually got this error because I was checking InnerHtml for some content that was generated dynamically - i.e. a control that is runat=server.
To solve this I had to remove the "static" keyword on my method, and it ran fine.
From my looking you give a null value to a textbox and return in a ToString() as it is a static method. You can replace it with Convert.ToString() that can enable null value.
Make the function static. This must solve your problem.
The essence, and solution, to your problem is this:
using System;
namespace myNameSpace
{
class Program
{
private void method()
{
Console.WriteLine("Hello World!");
}
static void Main(string[] args)
{
method();//<-- Compile Time error because an instantiation of the Program class doesnt exist
Program p = new Program();
p.method();//Now it works. (You could also make method() static to get it to work)
}
}
}
Here is what i want to do
// pseudo code
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 myForm = new Form1();
Application.Run(myForm);
while(true)
{
string a = readline();
}
form1.show(a)
In other words , I need the form always show the input. but the code above will stop after 'Application.Run(myForm);'. The reason I don't write such code in the form1 class is the main part of code is run on a machine learning engine written in F#, and because F# doesn't have a good visual designer. So I am trying to create a simple form1.dll, and use it to plot the result over time.
So my problem is I only can initialise the form, but I can't update it over time.
Any hints will be appreciated.
You're trying to do 2 things at the same time, so your application should reflect that by using 2 threads. Next, the Form's Show() method does not accept a string, so you need to implement your own method.
Here's a C# 2.0 WinForms solution. The program runs the thread and processes the console input:
static class Program
{
[STAThread]
private static void Main()
{
// Run form in separate thread
var runner = new FormRunner();
var thread = new Thread(runner.Start) {IsBackground = false};
thread.Start();
// Process console input
while (true)
{
string a = Console.ReadLine();
runner.Display(a);
if (a.Equals("exit")) break;
}
runner.Stop();
}
}
The FormRunner takes care about thread invocation:
internal class FormRunner
{
internal Form1 form = new Form1();
internal void Start()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(form);
}
private delegate void StopDelegate();
public void Stop()
{
if (form.InvokeRequired)
{
form.Invoke(new StopDelegate(Stop));
return;
}
form.Close();
}
private delegate void DisplayDelegate(string s);
public void Display(string s)
{
if (form.InvokeRequired)
{
form.Invoke(new DisplayDelegate(form.Display), new[] {s});
}
}
}
And Form1 just needs something to display:
public void Display(string s)
{
textBox1.Multiline = true;
textBox1.Text += s;
textBox1.Text += Environment.NewLine;
}
I want to realize to change current user in my application. I have the following code:
public class Framework
{
private MainForm mainForm = null;
... // other fields
public virtual void run()
{
if (appInitializer!=null)
{
ISecurityManager securityManager = appInitializer.SecurityManager;
if (securityManager!=null)
{
if (securityManager.DoLogin())
{
RegisterDefaultActionsGroup();
InitializePlugins(appInitializer.Plugins);
// Apply rights for user
ActionsManager.Inst.ApplySecurity(securityManager, securityManager.CurrentUser);
mainForm = new MainForm();
mainForm.Text = appInitializer.ApplicationTitle;
if (appInitializer.ApplicationIcon != null)
{
mainForm.Icon = appInitializer.ApplicationIcon;
}
CorrectFormSizes(mainForm);
Context[Constants.MainForm] = mainForm;
MenuManager.Inst.FillMenu(DefaultGroups.MAIN_MENU, mainForm.MainMenu, ActionClick);
if(appInitializer.IsHaveToCreatePanelInfo) PanelInfoManager.Inst.FillInfo(mainForm);
if (appInitializer.IsHaveToCreateToolBar)
{
MenuManager.Inst.FillToolbar(DefaultGroups.MAIN_TOOLBAR, mainForm.MainToolStrip, ActionClick);
}
mainForm.MainToolStrip.Visible = mainForm.MainToolStrip.Items.Count > 0;
NotifyPluginsAboutShowing(appInitializer.Plugins);
Application.Run(mainForm);
}
}
}
}
...//other methods
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Framework framework = new Framework(new EArchiveInitializer());
framework.run();
}
}
In the button for change user I have:
Framework.Instance.MainForm.MainMenuStrip.Items.Clear();
Framework.Instance.run();
But, I got error: Starting a second message loop on a single thread is not a valid operation. Use Form.ShowDialog instead.
I know that means this error, but I can't to rewrite my code.
Can you help me?
Thanks.
SOLUTION:
Rewrite the last line in run method:
if (!Application.MessageLoop)
Application.Run(mainForm);
else
mainForm.Show();
Thanks Jonathan.
The problem is actually quite easy, the issue is you are calling Application.Run twice (first on load, second on the button)
A quick work around for this, would be to have the Application.Run an ApplicationContext, instead of a form initially, and from your public virtual void run() method, load the required form.
public class Framework
{
private MainForm mainForm = null;
... // other fields
public virtual void run()
{
if (appInitializer!=null)
{
ISecurityManager securityManager = appInitializer.SecurityManager;
if (securityManager!=null)
{
if (securityManager.DoLogin())
{
RegisterDefaultActionsGroup();
InitializePlugins(appInitializer.Plugins);
// Apply rights for user
ActionsManager.Inst.ApplySecurity(securityManager, securityManager.CurrentUser);
mainForm = new MainForm();
mainForm.Text = appInitializer.ApplicationTitle;
if (appInitializer.ApplicationIcon != null)
{
mainForm.Icon = appInitializer.ApplicationIcon;
}
CorrectFormSizes(mainForm);
Context[Constants.MainForm] = mainForm;
MenuManager.Inst.FillMenu(DefaultGroups.MAIN_MENU, mainForm.MainMenu, ActionClick);
if(appInitializer.IsHaveToCreatePanelInfo) PanelInfoManager.Inst.FillInfo(mainForm);
if (appInitializer.IsHaveToCreateToolBar)
{
MenuManager.Inst.FillToolbar(DefaultGroups.MAIN_TOOLBAR, mainForm.MainToolStrip, ActionClick);
}
mainForm.MainToolStrip.Visible = mainForm.MainToolStrip.Items.Count > 0;
NotifyPluginsAboutShowing(appInitializer.Plugins);
mainForm.Show();
}
}
}
}
...//other methods
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MyHiddenContext());
}
}
public class MyHiddenContext
: ApplicationContext
{
private static Form activeFormInstance;
public MyHiddenContext()
{
this.RunFramework();
}
public void RunFramework()
{
Framework framework = new Framework(new EArchiveInitializer());
this.framework.run();
activeFormInstance = Framework.Instance.MainForm;
}
public static void ChangeUser()
{
activeFormInstance.Close();
activeFormInstance.Dispose();
Framework.Instance.MainForm.MainMenuStrip.Items.Clear();
Framework.Instance.run();
}
}
Don't quote me on the code actually working, but its more to give an idea on which way to go. The problem though is you can't call Application.Run more than once, so the principal is to have a containing instance or context (in any such sense, form, console etc)