C# Get Value of a text box in a Static Void - c#

I am trying to get the value of a text box called txtNum on the form FrmPhone as well as write to the text box txtLog however there seems to be no interacation between the Static Void and the Text Boxes on FrmPhone.
Below is the code for the CreateCall Static Void.
private void btnCall_Click(object sender, EventArgs e)
{
CreateCall();
}
static void CreateCall()
{
FrmPhone FrmPhone = new FrmPhone();
var numberToDial = FrmPhone.txtNum.Text;
FrmPhone.txtLog.Text += "\r\nCall " + numberToDial;
FrmPhone.txtLog.ScrollToCaret();
SetupDevices();
call = softphone.CreateCallObject(phoneLine, numberToDial);
call.CallStateChanged += call_CallStateChanged;
call.Start();
}
What am I missing to allow me to interact with the text boxes on the form while executing code in the static void?
Also worth noting is that If replace
var numberToDial = FrmPhone.txtNum.Text;
with
var numberToDial = "2788";
The call is made but the txtLog text does not change.

There are two options.
You make the method non-static. This is the easiest solution and the one that makes most sense. You are after all using instance variables.
void CreateCall()
{
var numberToDial = this.txtNum.Text;
}
Pass in the form to the method, as said, it doesn't make sense, but it does the job. txtNum needs to be internal or public, or CreateCall must reside in the same class:
static void CreateCall(FrmPhone frmPhone)
{
var numberToDial = frmPhone.txtNum.Text;
}
In calling the code you pass in this:
CreateCall(this);

Related

Passing a variable between forms WINFORMS [duplicate]

Wierd behaviour when passing values to and from second form.
ParameterForm pf = new ParameterForm(testString);
works
ParameterForm pf = new ParameterForm();
pf.testString="test";
doesn't (testString defined as public string)
maybe i'm missing something? Anyway I'd like to make 2nd variant work properly, as for now - it returns null object reference error.
Thanks for help.
Posting more code here:
calling
Button ParametersButton = new Button();
ParametersButton.Click += delegate
{
ParameterForm pf = new ParameterForm(doc.GetElementById(ParametersButton.Tag.ToString()));
pf.ShowDialog(this);
pf.test = "test";
pf.Submit += new ParameterForm.ParameterSubmitResult(pf_Submit);
};
definition and use
public partial class ParameterForm : Form
{
public string test;
public XmlElement node;
public delegate void ParameterSubmitResult(object sender, XmlElement e);
public event ParameterSubmitResult Submit;
public void SubmitButton_Click(object sender, EventArgs e)
{
Submit(this,this.node);
Debug.WriteLine(test);
}
}
result:
Submit - null object reference
test - null object reference
pf.ShowDialog(this); is a blocking call, so pf.Submit += new ParameterForm.ParameterSubmitResult(pf_Submit); is never reached: switch the order.
Submit(this,this.node); throws a null object reference because no event is assigned to it (see above). Generally, you should always check first: if (Submit != null) Submit(this,this.node);
You should change ``pf.ShowDialog(this);topf.Show(this);` so that your main form isn't disabled while your dialog box is open, if that's what you want, or use the model below (typical for dialog boxes.)
I'm not sure what pf_Submit is supposed to do, so this might not be the best way to go about it in your application, but it's how general "Proceed? Yes/No" questions work.
Button ParametersButton = new Button();
ParametersButton.Click += delegate
{
ParameterForm pf = new ParameterForm(testString);
pf.ShowDialog(this); // Blocks until user submits
// Do whatever pf_Submit did here.
};
public partial class ParameterForm : Form
{
public string test; // Generally, encapsulate these
public XmlElement node; // in properties
public void SubmitButton_Click(object sender, EventArgs e)
{
Debug.WriteLine(test);
this.Close(); // Returns from ShowDialog()
}
}
When you want to use your second variant, you have to use a getString()-Method, where you can put the e.g. "testString". The way you wrote it, "testString" should be a method (and got brackets).
EDIT (a bit more precise):
You could write:
pf.getString(testString);
, if "pf" is an instance of your own class, otherwise you had to look up, whether you can retrieve a String in this class.
the thing was in line order :)
pf.Submit += new ParameterForm.ParameterSubmitResult(pf_Submit);
and
pf.Test = "test";
should have been set before
pf.ShowDialog(this);
my mistake thingking that parameter can be passed after 2nd form was displayed
thnx for answers

Calling a function within a listener function

I'm new to the C# world and I am trying to call another function inside a listener using this code below:
private void Form1_Load(object sender, EventArgs e)
{
listener = new GestureListener(100);
listener.onGesture += listener_onGesture;
controller = new Controller(listener);
}
static void listener_onGesture(Gesture gesture)
{
string gestures = "";
foreach (Gesture.Direction direction in gesture.directions) {
gestures = direction.ToString();
}
int howManyFingers = gesture.fingers;
if (gestures == "Left" && howManyFingers == 2) {
test();
} else {
Console.WriteLine("gestured " + gestures + " with " + gesture.fingers + " fingers.");
}
}
private void test()
{
pdf.gotoNextPage();
}
However, it does not seem to work when i do that. The error it gives me on the line test(); is:
An object reference is required for the non-static field, method, or property 'LeapDemoTest.Form1.test()'
How can i do this?
You're seeing this because listener_onGesture is a static method -- meaning, the method is not associated with a given instance of your class. However, test is an instance method -- so it is scoped to the specific instance.
I see three options, depending on the scope of "pdf", but I recommend option 1:
Make listener_onGesture an instance method (remove the static keyword)
Make test a static method -- this will only work if pdf is also a static member.
Somewhat hackish -- find the Form instance that invoked the event by inspecting the sender's properties and invoke the test method on that instance.
listener_onGesture probably shouldn't be static. You want to access instance fields within this method, and you appear to be calling it from within an instance of the application (Form1_Load, where you currently reference it from, is not a static method). By removing the static modifier from that method you will then be able to call a non-static method.

C# - Writing to a multiline textbox

I'm trying to write the status of the program to the user. But my method to do so doesn't work. statusBox is a textbox windows form.
public static void writetoStatus(string text)
{
TextBox statusBox = new TextBox();
statusBox.Text = text;
}
Help please!
You can't access instance variables with a static method. I can't think of a way that statusBox would not be an instance member. Try making your method non-static and it should be fine.
As mentioned in a previous answer, your method needs to be static in order to access the TextBox on your form.
Also pressing, however is the fact that you're putting the status in a new TextBox instead of the one on your form.
If you created a form and put a TextBox on it, then the TextBox already has a name, and you can access it from the code-behind file. By default, I think it would be Textbox1 or some other number. You can, of course, change this name in the designer file or in the form editor GUI in Visual Studio.
So, lets say you change the name of the existing TextBox to statusBox. Now your method need only be this:
void WriteToStatus(string status)
{
statusBox.Text = status;
}
Ok, i see that you are creating a new instance of text box inside static method. That instance of textbox ends up nowhere and it's destroyed once you your static method is executed.
You can either have:
public static void writetoStatus(TextBox tb, string text)
{
tb.Text = text;
}
// and then later use it like:
writetoStatus(statusBox, text);
Or:
public static void writetoStatus(Form frm, string text)
{
TextBox tb = new TextBox();
tb.Text = text;
frm.Controls.Add(tb);
}
// and then later use it like:
writetoStatus(myForm, text);

C# Call function in a class from another class

I'll start of by saying I'm not a developer. Yes this is a c# nightmare. But this is a one time tool and thats it. Quick and Dirty it just needs to work and thats it.
I have the following code:
public string[] get_status(string local_fname)
{
var dts_doc = new HtmlAgilityPack.HtmlDocument();
dts_doc.Load(local_fname);
//Pull the values
var ViewState = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/#value[1]");
var EventValidation = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/#value[1]");
string ViewState2 = ViewState.Attributes[3].Value;
string EventValidation2 = EventValidation.Attributes[3].Value;
//Display the values
//System.Console.WriteLine(ViewState.Attributes[3].Value);
//System.Console.WriteLine(EventValidation.Attributes[3].Value);
//System.Console.ReadKey();
return new string[] { ViewState2, EventValidation2 };
}
I want to call get_status from a button on my Main.cs which will show 2 Message Boxes with ViewState2 and EventValidation2.
Again, I'm not a developer, this is probably the wrong way of doing things. But I just need a quick and dirty solution to get this job done once.
Make the function static by adding the static keyword to the function definition:
static public string[] get_status(string local_fname)
Use the class name to reference the function from your Main class.
try this:
foreach(string s in get_status(localFname))
{
MessageBox.Show(s);
}
As you said, it is quick and dirty and I stayed faithful to that paradigm.
And yes, if you need to acces another class, make the method static or just simply create an instance and call the method on it. I hope I have understood the problem correctly.
if you are using visual studio, go to the Button you want to click, double-click the button. This will create an eventhandler. In the eventhandler you should call the above method.
protected void Button1_Click(object sender, eventArgs e)
{
string local_fname = someValue;
string results[] = get_status(local_fname);
MessageBox.Show(results[0]);
MessageBox.Show(results[1]);
}

Need to set more than just a single property during Control.Invoke

I have been searching stackoverflow for ways to marshal data back from a thread to the UI thread, and have found various ways to do it in 3.5.
One of the more elegant solutions to me; although I am still learning lambdas and closures is this solution Control.Invoke with input Parameters.
I don't completely understand the code, but I do understand how to use it and it doesn't quite solve my problem.
I would like to call invoke and pass a string to another method (DisplayStatusUpdate(msg)). Any pointers would be appreciated.
private void FireEventAppender_OnMessageLogged(object sender, MessageLoggedEventArgs e)
{
DisplayStatusUpdate(e.LoggingEvent.RenderedMessage);
}
private void DisplayStatusUpdate(string text)
{
_StatusTextBox.Text = _StatusTextBox.Text + text;
_StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text);
_StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1;
_StatusTextBox.ScrollToCaret();
}
You can do this with as many parameters as you like, for example:
private void FireEventAppender_OnMessageLogged(object sender, MessageLoggedEventArgs e)
{
DisplayStatusUpdate(e.LoggingEvent.RenderedMessage);
}
private delegate void DisplayStatusUpdateDelegate(string text);
private void DisplayStatusUpdate(string text)
{
if(InvokeRequired)
this.Invoke(new DisplayStatusUpdateDelegate(DisplayStatusUpdate), text);
else
{
_StatusTextBox.Text = _StatusTextBox.Text + text;
_StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text);
_StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1;
_StatusTextBox.ScrollToCaret();
}
}
There is another method that I have been using in a current project that can reduct the code significantly. Details are here.
If you implement this method, you would need to:
Create the form using the AOP factory:
Form f = AOPFactory.Create<Form1>();
Application.Run(f);
And then you just decorate the event handler with the [RunInUIThread] attribute. It uses Castle's method interception model to automatically invoke if need be.
Thus, the above code becomes:
private void FireEventAppender_OnMessageLogged(object sender, MessageLoggedEventArgs e)
{
_StatusTextBox.Text = _StatusTextBox.Text + text;
_StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text);
_StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1;
_StatusTextBox.ScrollToCaret();
}
Performance wise it seems to be comparable, slightly slower, but depending on what you are doing it may be ok, it definitely takes less code.
If you are using C# 3.5 (or later) you can use captured variables, which may simplify the code:
private void DisplayStatusUpdate(string text)
{
this.Invoke(new MethodInvoker(() =>
{
_StatusTextBox.Text = _StatusTextBox.Text + text;
_StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text);
_StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1;
_StatusTextBox.ScrollToCaret();
}));
}
What the compiler will do behind the scenes here is to generate a class to hold the text, create a MethodInvoker delegate, and pass that delegate and an instance of the generated class to the Invoke method. In the above design this will of course do the unnecessary work of creating a delegate and calling Invoke even if the code is already running on the same thread; but I believe that a method like this should not be called that often that it would be a performance issue.
If you want to you can replace the use of MethodInvoker with the parameter-less Action delegate, or any other parameter-less delegate that returns void.

Categories

Resources