We need to show a Modal or a Toast notification on an ASP.net page whenever there is a new text file or there is some change in an existing text file. Here is what we've come up with:
private string htmsDir = "C:\\HTMS";
private string htmsDirPath = string.Empty;
FileSystemWatcher watcher;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
watcher = new FileSystemWatcher(htmsDir);
watcher.Filter = "*.txt";
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
watcher.EnableRaisingEvents = true;
}
}
private void watcher_Changed(object sender, FileSystemEventArgs e)
{
try
{
String[] lines = System.IO.File.ReadAllLines(e.FullPath);
if (lines.Length < 1)
return;
String line = lines[lines.Length - 1];
int counter = 1;
while (line == null || line.Length < 1)
{
counter++;
if (counter > lines.Length)
break;
line = lines[lines.Length - counter];
}
if (line == null || line.Length < 1)
return;
if (ParseHTMSData(line))
{
UpdateForm();
}
}
catch (Exception) { }
}
private bool ParseHTMSData(string line) {
return true;
}
private void UpdateForm()
{
try
{
Response.Write("this");
}
catch (Exception ex)
{
Common.logger.CreateDBLog(ex.ToString());
}
}
But the problem is functions like Response.Write(); are not working at all! And there is no proper Exception available to start with.
What are we doing wrong? is there any simpler way?
Related
i have POS system to fastfood, created by c# and sql server.
after the payment process show me window "Order Successfully Paid" after clicking to ok return to form ProductsReceiptPreview again,
i want after payment process go to the form main.
this is my code.......
private void lblPayments_Click(object sender, EventArgs e)
{
if (pnlPayments.Height != lbl.Height)
{
pnlPayments.Height = lbl.Height;
btnDone.Text = "DONE";
lbl.Text = "RECEIPT";
btnDone.Image = Resources.done;
Data.Show();
}
else
{
pnlPayments.Height = 394;
btnDone.Text = "RECEIPT";
lbl.Text = "AMOUNT";
btnDone.Image = Resources.receipt;
Data.Hide();
}
}
private void Touch_Click(object sender, EventArgs e)
{
var btn = (Button)sender;
txtCashReceived.Text += btn.Text;
}
private void btnClear_Click(object sender, EventArgs e)
{
if(txtCashReceived.Text.Length >0) txtCashReceived.Text =
txtCashReceived.Text.Remove(txtCashReceived.Text.Length - 1);
}
double totalBill = 0;
private void btnPay_Click(object sender, EventArgs e)
{
if (txtCashReceived.Text.Length > 0 && totalBill <=
Convert.ToInt32(txtCashReceived.Text) && Data.RowCount > 0)
{
int i = 0;
foreach (var rep in ListReports)
{
i++;
var report = new ModelReports();
report.Productname = rep.Productname;
report.TotalSales = rep.TotalSales;
report.TotalTransactions = rep.TotalTransactions;
report.Save();
}
var rpd = new ProductsReceiptPreview(dataReceiptBindingSource,
txtTotal.Text, txtCashReceived.Text, txtChange.Text);
rpd.ShowDialog();
if (i == ListReports.Count)
{
MessageBox.Show("Order Successfully Paid");
}
pnlProducts.Controls.Clear();
pnlCategoryPanel.Visible = false;
dataReceiptBindingSource.Clear();
LoadTables();
btnDone.PerformClick();
}
else
{
MessageBox.Show("Please pay your order.");
txtCashReceived.Text = "0";
}
}
private void btnPay_Click_1(object sender, EventArgs e)
{
if (txtCashReceived.Text.Length > 0 && totalBill <=
Convert.ToInt32(txtCashReceived.Text) && Data.RowCount > 0)
{
int i = 0;
foreach (var rep in ListReports)
{
i++;
var report = new ModelReports();
report.Productname = rep.Productname;
report.TotalSales = rep.TotalSales;
report.TotalTransactions = rep.TotalTransactions;
report.Save();
}
if (i == ListReports.Count)
{
MessageBox.Show("Order Successfully Paid");
txtCashReceived.Text = "0";
}
pnlProducts.Controls.Clear();
pnlCategoryPanel.Visible = false;
dataReceiptBindingSource.Clear();
LoadTables();
btnDone.PerformClick();
}
else
{
MessageBox.Show("Please pay your order.");
}
}
If you call some code from main then it will return to main when the call is finished. In the case of a Form, it's handled on a different thread started from main. The thread will never return back to main in this context. If you are using a click event to do some action and want to call some other code when that happens, then you need to re-design your infrastructure. Look into SOLID development principles and dependency injection.
https://www.codeproject.com/Tips/1033646/SOLID-Principle-with-Csharp-Example
https://simpleinjector.readthedocs.io/en/latest/windowsformsintegration.html
I am trying to display the results of my app in the listbox or textbox but neither is working. i don't know how to call the textBox1.Text
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
//listBox1.Items.Add(printPath());
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
I want to print the values from this method:
static void showPath(List<PathFinderNode> mPath)
{
TextBox tx = new TextBox();
ListBox ls = new ListBox();
var bn = new ListBox();
string disP = "nnnn";
MessageBox.Show("show path reached"); //method check
try
{
foreach (PathFinderNode node in mPath)
{
if ((node.X - node.PX) > 0) { disP = "Right"; }
if ((node.X - node.PX) < 0) { disP = "Left"; }
if ((node.Y - node.PY) > 0) { disP = "UP"; }
if ((node.Y - node.PY) < 0) { disP = "Down"; }
ls.Items.Add(disP);
tx.Text = disP;
bn.Text = disP;
}
}
catch (FormatException p)
{
Console.WriteLine(p.Message);
}
}
and yes, I get the message that says "show path reached" so I know the program reaches that point. just the display isn't working.
Why not make the method just return the path steps and let the caller decide how to handle it.
static string[] showPath(List<PathFinderNode> mPath)
{
List<string> paths = new List<string>();
string disP = string.Empty;
MessageBox.Show("show path reached"); //method check
try
{
foreach (PathFinderNode node in mPath)
{
if ((node.X - node.PX) > 0) { disP = "Right"; }
if ((node.X - node.PX) < 0) { disP = "Left"; }
if ((node.Y - node.PY) > 0) { disP = "UP"; }
if ((node.Y - node.PY) < 0) { disP = "Down"; }
paths.Add(disP);
}
}
catch (FormatException p)
{
Console.WriteLine(p.Message);
}
return paths.ToArray();
}
Then you can just call it like so:
listBox1.AddRange(showPath(...));
I created an OPC client to connect to KepServerEX, I got realtime data from KepServerEX and now I want to add realtime data to user control that contains a textbox.
Realtime data will be updated via value_changed event.
I created Windows Form Application and added textbox to Form to display realtime value, I can not post images here.
This is my code:
namespace OPC_Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
OPCServer KepServer;
OPCGroups KepGroups;
OPCGroup KepGroup;
OPCItems KepItems;
OPCItem KepItem;
string strHostIP = "";
string strHostName = "";
bool opc_connected = false;
int itmHandleClient = 0;
int itmHandleServer = 0;
private bool CreateGroup()
{
try
{
KepGroups = KepServer.OPCGroups;
KepGroup = KepGroups.Add("OPCDOTNETGROUP");
SetGroupProperty();
KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
KepGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(KepGroup_AsyncWriteComplete);
KepItems = KepGroup.OPCItems;
}
catch (Exception)
{
return false;
}
return true;
}
private void SetGroupProperty()
{
KepServer.OPCGroups.DefaultGroupIsActive = true;
KepServer.OPCGroups.DefaultGroupDeadband = 0;
KepGroup.UpdateRate = 1000;
KepGroup.IsActive = true;
KepGroup.IsSubscribed = true;
}
private void RecurBrowse(OPCBrowser OPCBrowser)
{
OPCBrowser.ShowBranches();
OPCBrowser.ShowLeafs(true);
listBox1.Items.Clear();
foreach (object turn in OPCBrowser)
{
bool bl = turn.ToString().Contains("System") ;
if (bl == false)
{
if (!Regex.IsMatch(turn.ToString(), #"^(\w+\.\w+\.\w+)$"))
{
}
else
{
listBox1.Items.Add(turn.ToString());
}
}
}
}
private bool ConnectRemoteServer(string remoteServerIP, string remoteServerName)
{
try
{
KepServer.Connect(remoteServerName, remoteServerIP);
}
catch (Exception ex)
{
MessageBox.Show(""+ex);
return false;
}
return true;
}
// Write the TAG value when executed event
void KepGroup_AsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
{
lblState.Text = "";
for (int i = 1; i <= NumItems; i++)
{
lblState.Text += "Tran:" + TransactionID.ToString() + " CH:" + ClientHandles.GetValue(i).ToString() + "Error:" + Errors.GetValue(i).ToString();
}
}
void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
for (int i = 1; i <= NumItems; i++)
{
if (Qualities.GetValue(i).ToString() == "192")
{
// add realtime value to texbox to display
txtTagValue.Text = ItemValues.GetValue(i).ToString();
txtQualities.Text = Qualities.GetValue(i).ToString();
txtTimeStamps.Text = TimeStamps.GetValue(i).ToString();
}
else
{
MessageBox.Show("disconnected to opc server");
txtQualities.Text = Qualities.GetValue(i).ToString();
txtTimeStamps.Text = TimeStamps.GetValue(i).ToString();
}
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (itmHandleClient != 0)
{
Array Errors;
OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
int[] temp = new int[2] { 0, bItem.ServerHandle };
Array serverHandle = (Array)temp;
KepItems.Remove(KepItems.Count, ref serverHandle, out Errors);
}
itmHandleClient = 1;
KepItem = KepItems.AddItem(listBox1.SelectedItem.ToString(), itmHandleClient);
itmHandleServer = KepItem.ServerHandle;
}
catch (Exception err)
{
itmHandleClient = 0;
txtTagValue.Text = "Error ox";
txtQualities.Text = "Error ox";
txtTimeStamps.Text = "Error ox";
MessageBox.Show("The reserved for system entry:" + err.Message, "message");
}
}
private void Form1_Load(object sender, EventArgs e)
{
//GetLocalServer();
KepServer = new OPCServer();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (!opc_connected)
{
return;
}
if (KepGroup != null)
{
KepGroup.DataChange -= new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
}
if (KepServer != null)
{
KepServer.Disconnect();
KepServer = null;
}
opc_connected = false;
}
private void btnSetGroupPro_Click(object sender, EventArgs e)
{
SetGroupProperty();
}
private void btnConnLocalServer_Click(object sender, EventArgs e)
{
try
{
if (!ConnectRemoteServer(txtRemoteServerIP.Text.Trim(), "KEPware.KEPServerEx.V5"))
{
return;
}
btnSetGroupPro.Enabled = true;
opc_connected = true;
GetServerInfo();
RecurBrowse(KepServer.CreateBrowser());
if (!CreateGroup())
{
return;
}
}
catch (Exception ex)
{
MessageBox.Show("" + ex);
}
}
private void btnWrite_Click(object sender, EventArgs e)
{
OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
int[] temp = new int[2] { 0, bItem.ServerHandle };
Array serverHandles = (Array)temp;
Object[] valueTemp = new Object[] { "", txtWriteTagValue.Text };
Array values = (Array)valueTemp;
Array Errors;
int cancelID;
KepGroup.AsyncWrite(1, ref serverHandles, ref values, out Errors, 2009, out cancelID);
GC.Collect();
}
}
}
Now I want to create some User Controls to display some tag values.What should I do?
This is a pretty big topic in itself, but I have implemented such a beast a few years back in C#, also using KepServerEx.
Without seeing your code it's a bit difficult for me to understand what you have done so far, but the general idea is that you want to handle the OPCGroup.DataChange event. From there you have to "dispatch" the changed value to the proper TextBox.
Of course, you have to setup your OPCServer, your OPCGroup(s) and so on.
I created a library for this, and it was some extensive work required, so I'm afraid it can't really be answered in one Q&A like here.
If you have a very specific question, please open another one and I'll try to answer more specifically.
Cheers
I'm trying to build a program that would take a picture of a user 3 times and save those pictures in the desktop my problem is it only saves the picture instead of taking the picture 3 times.
private void Form1_Load(object sender, EventArgs e)
{
bool useCam = true;
if (!useCam)
measureImage(null);
else
{
try
{
camera = new Capture();
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
return;
}
Application.Idle += viewImage;
captureProcess = true;
}
}
here is the capturing code...
private void btnCapture_Click(object sender, EventArgs e)
{
for (int ctr = 0; ctr < 3; ctr++)
{
if (captureProcess == true)
{
string data="";
Application.Idle -= viewImage;
SaveFileDialog dlg = new SaveFileDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
img.ToBitmap().Save(#"C:\\Users\\Julie\\Desktop\\" + ctr + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
data = dlg.FileName + ".bmp";
MessageBox.Show(data);
measureImage(data);
Form1_Load(sender, e);
}
else
{
Application.Exit();
}
}
}
captureProcess = false;
}
Presuming captureProcess is a variable at the window scope, you're setting it to false within the first for loop, so the 2nd and 3rd never execute due to the if(captureProcess == true) check.
I have created a code for my combobox, that can search addresses in a very large table on Sql Server with the help of stored procedure (i'm working with Entity framework). My stored procedure returns 10 hits and my code fills the combobox with search results. For doing this I'm using BackgroundWorker.
But here I'm now having big problems:
- although the combobox is filled with my search results, it always has the first item selected. Even if I type in only a letter, the whole text gets selected;
After that searching for the address doesn't work anymore. It searches only among these 10 results and I'm having no idea how to solve this. Here is my whole code, that causes me problems:
public String searchedItem = "";
public delegate void DelegateUpdateComboboxSelection(ComboBox myCombo,string value,int count);
BackgroundWorker m_bgworker = new BackgroundWorker();
static AutoResetEvent resetWorker = new AutoResetEvent(false);
m_bgworker.WorkerSupportsCancellation = true;
m_bgworker.DoWork += new DoWorkEventHandler(FillComboboxBindingList);
m_bgworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_bgworker_RunWorkerCompleted);
BindingList<spIskalnikNaslovi_Result1> m_addresses = new BindingList<SP_Result1>();
void m_bgworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
int count = (int)((object[])e.Result)[0];
string value = (string)((object[])e.Result)[1];
ComboBox myCombo = (ComboBox)((object[])e.Result)[2];
DelegateUpdateComboboxSelection ndelegate = new DelegateUpdateComboboxSelection(UpdateComboSelection);
if (this.InvokeRequired)
{
Invoke(ndelegate, new object[] {myCombo, value, count});
return;
}
else
{
UpdateComboSelection(myCombo, value, count);
return;
}
}
private void UpdateComboSelection(ComboBox myCombo, String value, int count)
{
myCombo = comboBox9;
myCombo.DataSource = m_addresses;
searchedItem = myCombo.Text;
if (count > 0)
{
myCombo.SelectionStart = value.Length;
myCombo.SelectionLength = searchedItem.Length - value.Length;
myCombo.DroppedDown = true;
}
else
{
myCombo.DroppedDown = false;
myCombo.SelectionStart = value.Length;
}
}
public void FillComboboxBindingList(object sender, DoWorkEventArgs e)
{
if (m_bgworker.CancellationPending)
{
resetWorker.Set();
e.Cancel = true;
return;
}
else
{
string value = (String)((Object[])e.Argument)[0];
List<SP_Result1> result;
result = _vsebina.SP_searcher(value).ToList<SP_Result1>();
m_addresses = new BindingList<SP_Result1>();
foreach (SP_Result1 rez in result)
{
if (m_addresses.Contains(rez))
{
continue;
}
else
{
m_addresses.Add(rez);
}
}
foreach (SP_Result1 r in m_addresses.ToArray())
{
if (!result.Contains(r))
{
m_addresses.Remove(r);
}
}
e.Result = new object[] { rezultat.Count, vrednost, null };
return;
}
}
private void comboBox9_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Back)
{
int searchStart = comboBox9.SelectionStart;
if (searchStart > 0)
{
searchStart--;
if (searchStart == 0)
{
comboBox9.Text = "";
}
else
{
comboBox9.Text = comboBox9.Text.Substring(0, searchStart + 1);
}
}
else
{
searchStart = 0;
}
e.Handled = true;
}
}
private void comboBox9_Enter(object sender, EventArgs e)
{
comboBox9.SelectionStart = 0;
comboBox9.SelectionLength = 0;
}
private void comboBox9_Click(object sender, EventArgs e)
{
comboBox9.Text = "";
}
private void comboBox9_KeyPress(object sender, KeyPressEventArgs e)
{
Search();
}
public void Search()
{
if (comboBox9.Text.Length < 4)
{
return;
}
else
{
if (m_bgworker.IsBusy)
{
m_bgworker.CancelAsync();
m_bgworker = new BackgroundWorker();
m_bgworker.WorkerSupportsCancellation = true;
m_bgworker.DoWork += new DoWorkEventHandler(FillComboboxBindingList);
m_bgworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_bgworker_RunWorkerCompleted);
}
m_bgworker.RunWorkerAsync(new object[] { comboBox9.Text, comboBox9 });
}
}
Maybe can someone enlighten me, what I'm doing wrong. This is first time, that I'm using BackgroundWorker. I have no idea, how
to achieve "search as you type" with combobox in any other way, because my datatable with addresses is quite large (million records).
Thanks in advance for any kind of help or code example.
Vladimir
Edit 1:
Ok, here is my code, before I have used BackGroundWorker. It worked, but it searches very very slow (it can take up to 10 seconds):
private void comboBox9_TextChanged(object sender, EventArgs e)
{
if (comboBox9.Text.Length < 4)
{
return;
}
else
{
FillCombobox(comboBox9.Text, comboBox9);
}
}
public void FillCombobox(string value, ComboBox myCombo)
{
List<spIskalnikNaslovi_Result1> result;
result = _vsebina.spIskalnikNaslovi1(value).ToList();
if (result.Count() > 0)
{
myCombo.DataSource = result;
myCombo.ValueMember = "HS_MID";
myCombo.DisplayMember = "NASLOV1";
var searchedItem = myCombo.Items[0].ToString();
myCombo.SelectionStart = value.Length;
myCombo.SelectionLength = searchedItem.Length - value.Length;
myCombo.DroppedDown = true;
}
else
{
myCombo.DroppedDown = false;
myCombo.SelectionStart = value.Length;
}
return;
}
Is there a way to speed this up without having backgroundworker?
make a button you will call searchbutton
and in click_event of this button call your search() method that run your backgroundworker
that fill the combobox
clear you key_press event of your combobox and it will work
the mistake is you key_press event that call every key stroke happening your search method
so retrieve it
You should get your items in a list, use that list to populate your combobox.
then set AutoCompleteMode property value to Suggest or Append or SuggestAppend and set AutoCompleteSoucre property value to ListItems.
For "Search as you Type", which is actually "Filter as you Type" more than search, you need to implement the OnKeyDown or KeyPressed event.
What you would do is take the search string, which is the current text at the time of the event, then filter the master list using that string. Normally one would use "Starts With" for the filtering, but you could also simply use "Contains". Then you live update the contents of the box with the results from the filter. This is accomplished by changing and refreshing the Datasource.
Here is my final solution without BackGroundWorker. It works quick with my large table, and is upgraded for using a stored procedure on SQL Server (if you use Entity Framework). I use Timer to make sure the user can find a value, that he is searching.
Here you can see the original solution, that I found on this site (thanks to Max Lambertini and algreat for the idea and working concept):
C# winforms combobox dynamic autocomplete
My solution:
private bool _canUpdate = true;
private bool _needUpdate = false;
List<spIskalnikNaslovi_Result1> dataFound;
private void comboBox12_TextChanged(object sender, EventArgs e)
{
if (_needUpdate)
{
if (_canUpdate)
{
_canUpdate = false;
refreshData();
}
else
{
restartTimer();
}
}
}
private void comboBox12_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Back)
{
int searchStart = comboBox12.SelectionStart;
if (searchStart > 0)
{
searchStart--;
if (searchStart == 0)
{
comboBox12.Text = "";
}
else
{
comboBox12.Text = comboBox12.Text.Substring(0, searchStart + 1);
}
}
else
{
searchStart = 0;
}
e.Handled = true;
}
}
private void comboBox12_TextUpdate(object sender, EventArgs e)
{
_needUpdate = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
_canUpdate = true;
timer1.Stop();
refreshData();
}
private void refreshData()
{
if (comboBox12.Text.Length > 1)
{
FillCombobox(comboBox12.Text, comboBox12);
}
}
private void restartTimer()
{
timer1.Stop();
_canUpdate = false;
timer1.Start();
}
private void FillCombobox(string value, ComboBox myCombo)
{
dataFound = _vsebina.spIskalnikNaslovi1(value).ToList();
if (dataFound.Count() > 0)
{
myCombo.DataSource = dataFound;
myCombo.ValueMember = "HS_MID";
myCombo.DisplayMember = "NASLOV1";
var searchedItem = myCombo.Items[0].ToString();
myCombo.SelectionStart = value.Length;
myCombo.SelectionLength = searchedItem.Length - value.Length;
myCombo.DroppedDown = true;
return;
}
else
{
myCombo.DroppedDown = false;
myCombo.SelectionStart = value.Length;
return;
}
}