How to transfer code from Console application to WinForms? - c#

I want to transfer my code to a WinForms.
I know how to create buttons, text, etc... and how to operate them.
The problem is that I made my code in a windows application, and I want to transform it to WinForms application. I don't know how to copy and paste the whole code, cause in the WinForms application there is no main method..
Here is my code that I am trying to transfer to WinForms:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TcpClient connection = new TcpClient("127.0.0.1", 5000);
StreamReader sr = new StreamReader(connection.GetStream());
StreamWriter sw = new StreamWriter(connection.GetStream());
string name2 = "";
while (true)
{
Console.WriteLine("Enter your name and press submit");
name2=Console.ReadLine();
if (name2 != "")
{
sw.WriteLine(name2);
break;
}
}
Console.WriteLine("Loop is over");
Thread t2 = new Thread(Reader);
t2.IsBackground = true;
t2.Start(connection);
while (true)
{
sw.WriteLine(Console.ReadLine());
sw.Flush();
}
}
public static void Reader(object o)
{
TcpClient con = o as TcpClient;
if (con == null)
return;
StreamReader sr = new StreamReader(con.GetStream());
while (true)
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine();
}
Console.WriteLine(sr.ReadLine());
Console.WriteLine();
}
}
}
}
Here is the Form that I have created:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}

In windows form application there is main method but it is in program.cs file and its starts your default form after you program starts execution.
You can add the the textbox in form and on button event get the text of the textbox.
String username = textboxusername.Text;
Similarly you can do all the things you want.
The code that you have written before was for console application and that is not the same for the windows form application.
You have to code differently for this.

Related

"while" loop in windows forms apllication - no window is opened (c#)

I am new to C# and I want to create a windows forms application, which shows (it must be visible!) one window with some information and buttons and also it loads a page from internet (with selenium and phantom.js - though it is deprecated) every minute. I've written something like this:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using OpenQA.Selenium;
using OpenQA.Selenium.PhantomJS;
namespace WindowsFormsApplication1
{
public partial class Someclass : Form
{
private void label1_Click(object sender, EventArgs e)
{
}
private void Someclass_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
// Shows some text "Hello friend"
MessageBox.Show("Hello friend!");
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello again", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
public Someclass()
{
InitializeComponent();
while (!IsDisposed)
{
MessageBox.Show("Now the page will be downloaded");
var driverService = PhantomJSDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
using (var driver = new PhantomJSDriver(driverService))
{
driver.Navigate().GoToUrl("http://stackoverflow.com/");
MessageBox.Show("Here we are going to open StackOverflow");
var questions = driver.FindElements(By.ClassName("fs-display2"));
foreach (var question in questions)
{
// This will display some text from stackoverflow main page.
Console.WriteLine(question.Text);
question.Click();
MessageBox.Show("This is stackoverflow: " + question.Text);
}
MessageBox.Show("Here we go");
}
System.Threading.Thread.Sleep(60000); // delay in microseconds
}
}
}
My problem is that if I use "while", my window does not appear (but the page from internet loads correctly - every 1 minute), and if I use "if" instead of "while", my window appears well, but, of cource, the page loading goes only one time. What can solve my problem?
It's a quite simple solution: your while loop is preventing your UI from Update. You have to bring your loop in an extra Thread, or just use a backgroundworker
Yes, friends, you were right. I have put (using panel of instruments-> Background Worker):
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
while (!IsDisposed)
{
......................
}
System.Threading.Thread.Sleep(60000); // delay in microseconds
}
inside my public partial class someClass : Form after public Someclass()
and also added:
backgroundWorker1.RunWorkerAsync(2000);
inside my public Someclass()
So now the code looks like:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using OpenQA.Selenium;
using OpenQA.Selenium.PhantomJS;
namespace WindowsFormsApplication1
{
public partial class Someclass : Form
{
private void label1_Click(object sender, EventArgs e)
{
}
private void Someclass_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
// Shows some text "Hello friend"
MessageBox.Show("Hello friend!");
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello again", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
public Someclass()
{
InitializeComponent();
backgroundWorker1.RunWorkerAsync(2000);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
while (!IsDisposed)
{
MessageBox.Show("Now the page will be downloaded");
var driverService = PhantomJSDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
using (var driver = new PhantomJSDriver(driverService))
{
driver.Navigate().GoToUrl("http://stackoverflow.com/");
MessageBox.Show("Here we are going to open StackOverflow");
var questions = driver.FindElements(By.ClassName("fs-display2"));
foreach (var question in questions)
{
// This will display some text from stackoverflow main page.
Console.WriteLine(question.Text);
question.Click();
MessageBox.Show("This is stackoverflow: " + question.Text);
}
MessageBox.Show("Here we go");
}
System.Threading.Thread.Sleep(60000); // delay in microseconds
}
}
}
and works fine.

Serial Port Data Received Event accessed from Multiple forms

I'm trying to make a windows form application in Visual Studio in C# and the purpose is to be able to communicate with an Arduino microcontroller. Right now I have 2 forms (Form1 and Form2) and I need to send and receive data from both windows to the microcontroller. I have defined a class SerialComms.cs in which there I start my serialPort and I have been able to send messages from both forms to the Arduino.
The problem is I don't know how to go about to receiving data from the Arduino as soon as the data is received. If I were to create the serialPort from one of the forms i would be able to create a function for DataReceived that will run anytime data is received but I don't know how to do that when I start my serialPort from a class. Any help?
Here is my code for both forms and my serialComms class:
Form1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
namespace Test_Comms
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
connectToArduino();
}
void connectToArduino()
{
try { SerialComms.SerialPort.Close(); }
catch { }
getAvailablePorts();
for (int i = 0; i < COMcomboBox.Items.Count; i++)
{
string inputMsg = "None";
string commport = COMcomboBox.GetItemText(COMcomboBox.Items[i]);
//Wait for Arduino message sent
//If not receieved go to next port
SerialComms.SerialPort.PortName = commport;
SerialComms.SerialPort.BaudRate = 9600;
SerialComms.SerialPort.Open();
try { SerialComms.SerialPort.Open(); }
catch { }
int counter1 = 0;
while (counter1 < 100)
{
inputMsg = SerialComms.SerialPort.ReadLine();
try { inputMsg = SerialComms.SerialPort.ReadLine(); }
catch { }
counter1++;
if (inputMsg == "Arduino")
{
counter1 = 1000;
}
}
if (inputMsg != "Arduino")
{
try { SerialComms.SerialPort.Close(); }
catch { }
}
else
{
i = COMcomboBox.Items.Count;
SerialComms.SerialPort.WriteLine("Connection Established");
toolStripStatusLabel1.Text = "Connected";
break;
}
}
}
void getAvailablePorts()
{
COMcomboBox.Items.Clear();
String[] ports = SerialPort.GetPortNames();
COMcomboBox.Items.AddRange(ports);
}
private void button1_Click(object sender, EventArgs e)
{
SerialComms.SerialPort.WriteLine("LED ON");
}
private void button2_Click(object sender, EventArgs e)
{
SerialComms.SerialPort.WriteLine("LED OFF");
}
private void button3_Click(object sender, EventArgs e) //Opens second form
{
Form2 settingsForm = new Form2();
settingsForm.ShowDialog();
}
}
}
Form2
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
namespace Test_Comms
{
public partial class Form2 : Form
{
public static string text = "Test text";
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SerialComms.SerialPort.WriteLine("LED ON");
}
private void button2_Click(object sender, EventArgs e)
{
SerialComms.SerialPort.WriteLine("LED OFF");
button2.Text = text;
}
private void Form2_Load(object sender, EventArgs e)
{
}
}
}
SerialComms.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.IO;
namespace Test_Comms
{
public static class SerialComms
{
//public static delegate void DataReceivedEventHandler(object sender, ReceivedEventArgs e);
//public static event DataReceivedEventHandler DataReceived;
private static SerialPort _serialPort = new SerialPort();
public static SerialPort SerialPort
{
get { return _serialPort; }
set { _serialPort = value; }
}
}
}

l versC# multithread issue

I cannot get the ui thread to update the ui while the file copy thread is running. My end goal is to have the animation continue to rotate until the large file copy finally completes to let the user know that the program is not frozen. It's a very simple server to server file copy program.
Can someone tell me what I'm doing wrong?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Threading.Tasks;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void ResetProgress()
{
lblStep1.Image = null;
}
private void SetupProgress()
{
lblStep1.Image = global::animation1.Properties.Resources.animation;
}
private void fileCopy()
{
File.Copy("large file source", "large file destination", true);
}
private void Form1_Load(object sender, EventArgs e)
{
lblStep1.Image = global::animation1.Properties.Resources.animation;
}
private async void button1_Click(object sender, EventArgs e)
{
SetupProgress();
await Task.Run(() => fileCopy());
ResetProgress();
}
private void btnStop_Click(object sender, EventArgs e)
{
// unhandled currently
}
}
}
* Original version *
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Threading.Tasks;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Thread workItemsProducerThread;
private Thread workItemsCopyThread;
public Form1()
{
InitializeComponent();
}
private void ResetProgress()
{
lblStep1.Image = null;
}
private void SetupProgress()
{
this.BeginInvoke((MethodInvoker)delegate ()
{
lblStep1.Image = global::animation1.Properties.Resources.animation;
});
}
private void fileCopy()
{
File.Copy("Large file source", "Large file destination", true);
this.BeginInvoke((MethodInvoker)delegate ()
{
MessageBox.Show("Done");
});
}
private void Form1_Load(object sender, EventArgs e)
{
lblStep1.Image = global::animation1.Properties.Resources.animation;
}
private void btnStart_Click(object sender, EventArgs e)
{
this.workItemsProducerThread = new Thread(new ThreadStart(this.SetupProgress));
this.workItemsProducerThread.IsBackground = true;
this.workItemsProducerThread.Start();
this.SetupProgress();
this.workItemsCopyThread = new Thread(new ThreadStart(this.fileCopy));
this.workItemsCopyThread.IsBackground = true;
this.workItemsCopyThread.Start();
while (workItemsCopyThread.IsAlive)
{
Thread.Sleep(1000); // wait
}
MessageBox.Show("Done");
}
private void btnStop_Click(object sender, EventArgs e)
{
if (this.workItemsProducerThread != null)
{
this.workItemsProducerThread.Abort();
lblStep1.Image = global::animation1.Properties.Resources.animation;
}
}
private void btnTest_Click(object sender, EventArgs e)
{
fileCopy();
}
}
}
Don’t sleep in your click handler. That freezes the UI thread. Just let the clock handler exit. In your file copy thread, when the copy is don’t. Use Invoke(or BeginInvoke) to cause the done messagebox to pop up on the UI thread.
Try this oldy style
private void SetupProgress()
{
Invoke((MethodInvoker) delegate
{
lblStep1.Image = global::animation1.Properties.Resources.animation;
});
}
private Thread TDoSomeWork()
{
var t = new Thread(() => DoSomeWork());
t.Start();
return t;
}
TDoSomeWork();

How to set webbrowser documenttext from another form?

i create a simple message box to get user input and set the result into webbrowser of previous form.
this is my MsgInput source code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
public partial class MsgInput : Form
{
private readonly Main mainForm;
public string input_type;
string script;
public MsgInput()
{
this.mainForm = mainForm;
InitializeComponent();
}
private void MsgInput_Load(object sender, EventArgs e)
{
if (input_type == "echo")
{
richTextBox1.Text = "Echo : void echo ( string $arg1 [, string $... ] )";
}
}
private void btnOk_Click(object sender, EventArgs e)
{
if (input_type == "echo")
{
script = mainForm.webBrowser1.DocumentText;
if (chkNewLine.Checked == true)
{
script += "\n";
}
script += "echo " + txtInput.Text;
mainForm.webBrowser1.DocumentText = script;
this.Close();
}
}
}
and i not add anything in first form just set the webbrowser modifiers to public.
when i debug. null return when i try to submit an text
Main Form
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace EasyPHP
{
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
private void echoToolStripMenuItem_Click(object sender, EventArgs e)
{
var msg = new MsgInput();
msg.input_type = "echo";
msg.Show();
}
private void Main_Load(object sender, EventArgs e)
{
webBrowser1.DocumentText = "<pre>";
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
}
}
I am assuming you are getting a null reference exception. it will be useful if you post the main form code. From what i understood, you should be passing in the main form reference and that's why you are getting a null reference.
In your code, change the constructor as below (ParentForm is whatever is the class name of your parent form)
public MsgInput(ParentForm mainForm)
{
this.mainForm = mainForm;
InitializeComponent();
}
and in the main form
MsgInput frm = new MsgInput(this);
frm.input_type = "echo";
frm.Show(this);
Else please share the full code and we can quickly help

loading information from a file into a window

I have the following form. The first button opens a text file and displays the file in the rich text box in the form. The second button opens another window. What I want is for that window to be pre-populated with the data that is in that text file...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace HomeInventory2
{
public partial class Form2 : Form
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, System.EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
richTextBox1.LoadFile(openFileDialog1.FileName, RichTextBoxStreamType.RichText);
}
}
private void button2_Click(object sender, EventArgs e)
{
Application.Run(new Form1());
}
}
}
The form that needs to be populated
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using HomeInventory2.Domain;
using HomeInventory2.Business;
namespace HomeInventory2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void submitButton_Click(object sender, EventArgs e)
{
CreateInventory create = new CreateInventory();
create.ItemAmount = textBoxAmount.Text;
create.ItemCategory = textBoxCategories.Text;
create.ItemProperties = textBoxValue.Text;
create.ItemValue = textBoxValue.Text;
InventoryMngr invtryMngr = new InventoryMngr();
invtryMngr.Create(create);
}
}
}
Create a new constructor which takes a string overload. When you open the new Form, pass in the text date and fill the textbox.
//in the new form that opens up
public Form1(string prepopulated)
{
InitializeComponent();
myRichTextbox.Text = prepopulated;
}
And call it from your click event like this:
//in the first form
private void button2_Click(object sender, EventArgs e)
{
Application.Run(new Form1(richTextBox1.Text));
}
If your content is more complicated than a simple text file, you can use RichTextBox.Document instead and pass that instead of the string. Change the overload to
Form1(FlowDocument prepopulated)
and call it like this
Application.Run(new Form1(richTextBox1.Document));

Categories