Remake button method to call from constructor or any event - c#

Is there any way how I can call method img_Tapped without tap(not when I click on UI element(button))but call it for example from constructor? I have handler to MessageReceived. If no anyone can advise how I can remake these two methods for the same function - I dont need click element these method should be performed when is app started or page loaded ...
method 1:
private async void img_Tapped(object sender, TappedRoutedEventArgs e)
{
...
mws = new MessageWebSocket();
mws.Control.MessageType = SocketMessageType.Binary;
mws.MessageReceived += MessageReceived;
await mws.ConnectAsync(server);
messageWriter = new DataWriter(mws.OutputStream);
messageWriter.WriteBytes(buff);
await messageWriter.StoreAsync();
}
method 2:
private void MessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
{
try
{
using (DataReader reader = args.GetDataReader())
{
reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
byte[] read = reader.ReadBuffer(reader.UnconsumedBufferLength).ToArray();
}
}
catch (Exception ex)
{
}
}
.
.
.
I find this but its not good because click/tap on button is still needed and I dont want it.
img.Tapped += new TappedEventHandler(my method with button parameters);

Related

Console within form Visual C#

I want to get a console window within my form. Basically when you click button1, it runs a batch script(test.exe). I don't want a separate batch window but instead I want it to show up within my form.
I figure there are probably two ways of doing this, either 1, somehow embedding the console within my form, or 2, set StartInfo.CreateNoWindow = true; when you click button1 and get the output to funnel into a listbox to simulate a console within my form.
I am just a little stuck because I have found methods for doing both but my own testing with the various other methods people have suggested, nothing has worked. But either way, my user needs to be able to send input back to the console.
Which method would be simpler and how would I go about it?
I believe the best way to do this is to redirect output. Basically things will still execute as you want, but you will get the output wherever you want/need.
using System;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
namespace ConsoleOutput_test
{
public partial class Form1 : Form
{
Process sortProcess;
private static StringBuilder sortOutput = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
sortProcess = new Process();
sortProcess.StartInfo.FileName = "C:\\Windows\\System32\\cmd.exe";
// Set UseShellExecute to false for redirection.
sortProcess.StartInfo.CreateNoWindow = true;
sortProcess.StartInfo.UseShellExecute = false;
// Redirect the standard output of the sort command.
// This stream is read asynchronously using an event handler.
sortProcess.StartInfo.RedirectStandardOutput = true;
sortProcess.StartInfo.RedirectStandardInput = true;
sortProcess.StartInfo.RedirectStandardError = true;
sortOutput = new StringBuilder("");
// Set our event handler to asynchronously read the sort output.
sortProcess.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
sortProcess.ErrorDataReceived += new DataReceivedEventHandler(SortErrorHandler);
// Redirect standard input as well. This stream
// is used synchronously.
sortProcess.StartInfo.RedirectStandardInput = true;
// Start the process.
sortProcess.Start();
// Start the asynchronous read of the sort output stream.
sortProcess.BeginOutputReadLine();
while (!sortProcess.HasExited)
{
Application.DoEvents(); // This keeps your form responsive by processing events
}
}
private void SortOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (txtConsole.InvokeRequired) { txtConsole.BeginInvoke(new DataReceivedEventHandler(SortOutputHandler), new[] { sendingProcess, outLine }); }
else
{
txtConsole.AppendText(Environment.NewLine + outLine.Data);
}
}
private void SortErrorHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (txtConsole.InvokeRequired) { txtConsole.BeginInvoke(new DataReceivedEventHandler(SortErrorHandler), new[] { sendingProcess, outLine }); }
else
{
txtConsole.AppendText(Environment.NewLine + outLine.Data);
}
}
private void button2_Click(object sender, EventArgs e)
{
sortProcess.StandardInput.WriteLine(txtOutput.Text);
txtOutput.Text = "";
}
}
}

C# - Make UI function during like a infinite loop until button pressed

i make a code in C# where i extract some records from an Access database , but i need the while going to the next iteration to depend on the click of a button. i tried with some Thread or Tasks , but it didn't worked because it blocked the UI which i need it to be seen and clickable.
Here's the code:
bool nextClick = false ;
while (readerSelect.Read())
{
// show the correct panel
if (string.Compare(readerSelect[2].ToString(), "P1") == 0)
{
// panel with type 1
textBoxP1Text1.Text = readerSelect[3].ToString();
textBoxP1Text2.Text = readerSelect[4].ToString();
pictureBoxP1Image.ImageLocation = readerSelect[6].ToString();
}
else
{
// panel with type 2
textBoxP1Text2.Text = readerSelect[5].ToString();
}
//this while need to be kind of infinite so the interation can't be processed and
//so when i need to change iteration i click the buttonNext
while (!nextClick) {
startWhile:;
MethodInvoker mi = delegate () {
if (nextClick)
{
Application.DoEvents();
// System.Windows.Forms.Application.Run();
}
};
this.Invoke(mi);
//break;
goto startWhile;
}
private void buttonNext_Click(object sender, EventArgs e)
{
// click on the next button
nextClick = true;
}
You can use a semaphore within an async task, have the button Release it during each click, and have the while loop await it each time through. Here's a quick example, using a form that has a button1 and a label1 added to it:
public partial class Form1 : Form
{
private readonly SemaphoreSlim signal = new SemaphoreSlim(0, int.MaxValue);
public Form1()
{
this.InitializeComponent();
this.RunLoop();
}
private async void RunLoop()
{
var i = 0;
while (true)
{
this.label2.Text = $"Enqueued: {this.signal.CurrentCount}";
await this.signal.WaitAsync(); // Wait button click async
await Task.Delay(1000); // Simulate work
this.label1.Text = $"Completed: {++i}";
}
}
private void button1_Click(object sender, EventArgs e)
{
this.signal.Release();
this.label2.Text = $"Enqueued: {this.signal.CurrentCount + 1}";
// Or if you want to limit the # people can queue up, then put this whole
// thing in an `if (signal.CurrentCount < myLimit)` block, and optionally
// disable the button once limit has been reached, and re-enable it right
// before the `WaitAsync` call above.
}
}
While Dax Fohl's answer works, it seems like you've got a problem in your design. I think you're violating the Single Responsibility Principle by having too much business logic going on in the Form class.
I'd recommend factoring out the business logic into its own class. Then rather than running through everything in a loop, you simply have the button click event process the next record and display the result. Here's an example of what I mean:
public partial class Form1 : Form
{
private readonly DataProcessor dataProcessor = new DataProcessor();
public Form1()
{
this.InitializeComponent();
}
private void button1Next_Click(object sender, EventArgs e)
{
this.buttonNext.Enabled = false;
this.ProcessNext();
}
private async void ProcessNext()
{
string s = await this.dataProcessor.ProcessNext();
this.textBoxP1Text1.Text = s;
this.buttonNext.Enabled = true;
}
}
public class DataProcessor
{
private readonly Random r = new Random(); // Or reader or whatever.
public async Task<string> ProcessNext() // Just using `string` as an example.
{
await Task.Delay(1000);
return this.r.Next().ToString();
}
}
I think this will be easier to understand and more maintainable in the future. When a new team member looks at semaphore stuff (or your future self), it'll be hard to understand/remember what the point of all that was. Here, you just have a local function that does one thing and is easy to follow.

wcf call completed event is not fired in correct order

In my Silverlight application, I put the WCF call in my ViewModel class.
DateTime CurrentDateTime;
internal void GetDateTime()
{
var client = new WcfClient();
client.GetCurrentDateTimeCompleted += GetCurrentDateTimeCompleted;
client.GetCurrentDateTimeAsync();
}
private void GetCurrentDateTimeCompleted(object sender, GetCurrentDateTimeCompletedEventArgs args)
{
try
{
CurrentDateTime = args.Result;
}
Then in my code behind code some.xaml.cs file. I have a checkbox clicked event.
private void CheckBox_Clicked(object sender, RoutedEventArgs e)
{
var msgBoxControl = new MessageBoxControl();
msgBoxControl.Closed -= MessageBoxYesNo_Closed;
msgBoxControl.Closed += MessageBoxYesNo_Closed;
Inside the method MessageBoxYesNo_Closed, I call the method in the ViewModel class.
private void MessageBoxYesNo_Closed(object sender, EventArgs e)
{
try
{
this.ViewModel.GetDateTime();
curDateTime = this.ViewModel.CurrentDateTime;
My question is that sometimes the line curDateTime = this.ViewModel.CurrentDateTime; is executed before wcf call completed method, so I can't get the right value.
I guess that it may be there are two threads, one is in UI, the other one is in service call? Please don't use async/await as I have to use Visual Studio 2010.
Thanks
Get the solution, just add a while loop:
this.ViewModel.GetDateTime();
while (true)
{
this.ViewModel.CurrentDateTime = DateTime.Now;
if (this.ViewModel.CurrentDateTime != DateTime.MinValue)
break;
}
curDateTime = this.ViewModel.CurrentDateTime;

Form not loading correctly

I'm trying to build a TAPI based phone call system using JulMar's Atapi x86. One of the functions is to pop a specific form on an inbound call. However, whenever the form pops, it comes up incorrect, as shown below (I have tried several forms as a test and they all do the same thing). There is no error, nothing in the output window to suggest what the issue is.
Code:
private void incomingcall(object sender, NewCallEventArgs e)
{
string phonenumber = e.Call.CallerId; //get the phone number of the call
SqlCommand getincoming = new SqlCommand(Querystrings.getincomingquery(), DB);
getincoming.Parameters.AddWithValue("##TELEPHONE", phonenumber);
DataTable results = new DataTable();
try
{
DB.Open();
using (var results = getincoming.ExecuteReader())
{
results.Load(results);
}
}
catch (Exception ex)
{
Inbound ib = new Inbound(phonenumber, null);
ib.Show();
}
finally
{
DB.Close();
}
if (results.Rows.Count == 1)
{
loadcontactrequest(Convert.ToInt32(results.Rows[0].ItemArray[0]), phonenumber);
}
else
{
loadinbound(phonenumber, results);
}
}
I have loaded these forms outside of this function at other points, meaning it is something to do with this function. Does anybody know where I'm going wrong?
EDIT:
private void loadcontactrequest(int ContactID, string phonenumber)
{
ContactRequest cr = new ContactRequest(ContactID, Global.loginbound("Single customer found", phonenumber));
cr.Show();
}
These functions have been tested elsewhere and work correctly individually, I believe it might be TAPI related.
EDIT 2 - Delegate:
public static void inittapi()
{
if (TestOptions.notapi)
return;
tapi = new TapiManager("Omitted");
tapi.Initialize();
foreach (TapiLine ad in tapi.Lines) //Get all lines available to this PC
{
if (ad.Name.ToUpper().Contains("Omitted"))
{
phoneline = ad;
phoneline.Open(MediaModes.All); //Open the phone line for making and receiving calls
phoneline.NewCall += new EventHandler<NewCallEventArgs>(new TAPI().incomingcall); //Add the incoming call event handler
}
}
}
It's possible that this event is triggered on a different thread than the UI thread of your application.
Modify the method like this to test whether this is the problem:
private void incomingcall(object sender, NewCallEventArgs e)
{
Form form;
if(Application.OpenForms.Count > 0)
{
form = Application.OpenForms[0];
}
if (form != null && form.InvokeRequired)
{
form.BeginInvoke(new Action(() => { incomingcall(sender, e); }));
return;
}
// Your current code goes here
}
This will identify that we are in a different thread than your main form (form) was created on and then execute the function again on the main form's thread.

When is taking a photo done?

I'm working on a wp8-app that takes a photo and then takes you to the next screen to decide whether you like it or not.
The current approach was this:
private void ShutterButton_Click(object sender, RoutedEventArgs e)
{
if (cam != null)
{
try
{
cam.CaptureImage();
await Task.Delay(1500);
NavigateFront();
}
catch (Exception ex)
{
...
}
}
}
public void NavigateFront()
{
string naviString = "/confirmPicture.xaml?parameter=" + fileName.ToString();
_rootFrame.Navigate(new Uri(naviString, UriKind.Relative));
}
On my Lumia 520 it crashed sometimes. If I increase the wait-time to 2,5sec it works. But of course this should not be the way to do it.
If I catch the void cam_CaptureImageAvailable(object sender, Microsoft.Devices.ContentReadyEventArgs e)-Event and try to navigate after everything is done and all streams are closed I still get in a NavigateFailed-State and the app crashes.
My question is: is there any other useful event that ensures that all work is done and I can navigate without using static time-based values?
Navigation with a PhotoCamera is possible, just subscribe to its CaptureCompleted event handler
cam.CaptureCompleted += new EventHandler<CameraOperationCompletedEventArgs>(camera_CaptureCompleted);
and this would be the event
void camera_CaptureCompleted(object sender, CameraOperationCompletedEventArgs e)
{
try
{
Deployment.Current.Dispatcher.BeginInvoke(delegate()
{
try
{
cam.Dispose();
NavigationService.Navigate(new Uri("URI nething", UriKind.Relative));
}
catch (Exception)
{
MessageBox.Show("Problem occured!!");
}
});
}
catch
{
MessageBox.Show("Problem in camer_capturecompleted");
}
}
I did it in one of my apps targeting windows phone 7. Check if this works for you as well.

Categories

Resources