I want to run a method inside serialport_DataReceived event.
public void Draw(byte[] data);
private void myPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
this.Invoke(new EventHandler(DrawingAudioData(data)));
}
This is not work. It gives an error that say "Method name expected". What can i do?
Try
public delegate void Draw(byte[] data);
private void myPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
this.Invoke(new Draw(DrawingAudioData), data);
}
Seems to me that the DrawingAudioData passed to Invoke does not have EventHandler signature. Also you should pass the method Name to the delegate constructor.
The DrawingAudioData method should have the signature that matches the Draw delegate:
public void DrawingAudioData(byte[] data) {
More information about Event Handler here.
More information about the Delegate and Invoke method here.
Related
I am trying to call a OnCellEditEnding event from another event,
private void BillsTableRecords_OnCellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
// do stuff here
}
My issue is I don't know how to pass the DataGridCellEditEndingEventArgs into the method, i.e. the e in the below method obviously gives an error as it is referencing RoutedEventArgs not DataGridCellEditEndingEventArgs.
private void BillsRecordsCheckBox_OnChecked(object sender, RoutedEventArgs e)
{
BillsTableRecords_OnCellEditEnding(sender, e);
}
So how do obtain the value from DataGridCellEditEndingEventArgs so that I can pass the value in the method? Please note that the DataGrid cell with be selected at this point so it will contain a value.
I wouldn't recommend this approach. Event handlers are to be called by events; their signature does not really fit for a standalone call. In case you execute business code in your event handler, it is also not good design, because your event handlers are UI code, which should be separated from business code.
The best way to go here is to create a dedicated method that does what you want and call it from both event handlers:
private void DoStuff(/* add the parameters you need*/) {
//do stuff
}
private void BillsTableRecords_OnCellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
DoStuff();
}
private void BillsRecordsCheckBox_OnChecked(object sender, RoutedEventArgs e)
{
DoStuff();
}
try that
private void BillsRecordsCheckBox_OnChecked(object sender, RoutedEventArgs e)
{
BillsTableRecords_OnCellEditEnding(sender, new DataGridCellEditEndingEventArg());
}
If you want to keep the arguments from the RoutedEventArgs, add them to the constructor of DataGridCellEditEndingEventArg
I need to add an element to a Winform ListView control from other thread, so I am using a delegate, this way:
private delegate void AddMessageLogCallback(string message);
public void AddMessageLog(string message)
{
if (InvokeRequired)
Invoke(new AddMessageLogCallback(AddMessageLog), message);
else
{
lstLogs.Items.Add(message).EnsureVisible();
}
}
The problem is that the Invoke does nothing, not even throws an exception.
I have used this kind of delegates before and never had problems. What different is at this time?
Your code works as desired with the test code below, so the problem should be something else.
private void button1_Click(object sender, EventArgs e)
{
AddMessageLog("local message");
}
private async void button2_Click(object sender, EventArgs e)
{
await Task.Run(() => AddMessageLog("async message"));
}
Btw, I would mention that there is no need to define a new AddMessageLogCallback delegate and to call the AddMessageLog recursively. So a more simple (and maybe cleaner) solution:
public void AddMessageLog(string message)
{
Action addLog = () => lstLogs.Items.Add(message).EnsureVisible();
if (InvokeRequired)
Invoke(addLog);
else
addLog();
}
I have two forms, a FormMain, and a FormInputTagName. The FormMain uses FormInputTagName as a dialog to get a string from the user.
For this I've declared a delegate in FormInputTagName, here's the code:
public partial class FormInputTagName : Form
{
public delegate void ResultDelegate(string tagName);
public ResultDelegate _resultDelegate;
public void InputTagName(ResultDelegate resultDelegate)
{
this.ShowDialog();
_resultDelegate = resultDelegate;
}
private void Ok_Click(object sender, EventArgs e)
{
this.Hide();
_resultDelegate(textBoxElementTagName.Text);
}
}
Just in case, _resultDelegate is public, but it doesn't solve the problem.
In the FormMain, I have a method, with the signature as delegate declares:
public void AddElement(string tagName)
{
MessageBox.Show(tagName);
}
And a code (also in FormMain), that calls FormInputTagName passing AddElement as a delegate instance to it:
private void addToolStripMenuItem_Click(object sender, EventArgs e)
{
FormInputTagName inputForm = new FormInputTagName();
inputForm.InputTagName(new FormInputTagName.ResultDelegate(AddElement));
}
And when I run the program and type some text into textBoxElementTagName and click Ok button, it throws System.NullReferenceException at line
_resultDelegate(textBoxElementTagName.Text);
What can be a cause? Can it be that I call delegate in synchronous manner and should I call it using BeginInvoke / EndInvoke ?
And one more thing - if I do not save delegate into a class member _resultDelegate, but call it immediately, like that
public void InputTagName(ResultDelegate resultDelegate)
{
this.ShowDialog();
resultDelegate("qwer");
}
it works fine and calls AddElement function.
I'm just creating a ContextMenu..
At this line, I don't know what I shall put in the third param (or better: how I have to form it -syntaxly-):
(contextMenuStrip.Items[0] as System.Windows.Forms.ToolStripMenuItem).DropDownItems.Add(contextUnterMenuStrip.Items.Add(exe),null, HERE);
on 'HERE' I have to set an EventHandler onClick
By Example I got this Method:
public void DoSomething()
{
//...
}
How could I call this Method? (Over the Eventhandler?) or do I have to make a Method like:
private void button_Click(object sender, RoutedEventArgs e)
{
//...
}
Don't "call" the method but take its address. Which means omitting the ()
private void menuItem1_Click(object sender, EventArgs e)
{
//...
}
// your code, I think it misses a few ')'
... (contextMenuStrip.Items[0] as System.Windows.Forms.ToolStripMenuItem)
.DropDownItems.Add(contextUnterMenuStrip.Items
.Add(exe),null, menuItem1_Click);
As you can see here, the callback has to have the following prototype:
public delegate void EventHandler( Object sender, EventArgs e )
So your method DoSomething has to look like:
private void DoSomething(object sender, EventArgs e)
{
//...
}
You can create an anonymous event handler using the Linq libraries and call your method that way. This can be a nice and quick way of doing something (especially if it's just a test project). But if you start using it extensively, it might become difficult to read it.
An example of this would be:
var menuItem1 = new MenuItem();
menuItem1.Click += (sender, e) => DoSomething();
Refer here for further information on using Linq: http://msdn.microsoft.com/library/bb308959.aspx
I have a DirectoryMonitor class which works on another thread.
It has the following events declared:
public class DirectoryMonitor
{
public event EventHandler<MonitorEventArgs> CreatedNewBook;
public event EventHandler ScanStarted;
....
}
public class MonitorEventArgs : EventArgs
{
public Book Book { get; set; }
}
There is a form using that monitor, and upon receiving the events, it should update the display.
Now, this works:
void DirectoryMonitor_ScanStarted(object sender, EventArgs e)
{
if (InvokeRequired)
{
Invoke(new EventHandler(this.DirectoryMonitor_ScanStarted));
}
else {...}
}
But this throws TargetParameterCountException:
void DirectoryMonitor_CreatedNewBook(object sender, MonitorEventArgs e)
{
if (InvokeRequired)
{
Invoke(new EventHandler<MonitorEventArgs>(this.DirectoryMonitor_CreatedNewBook));
}
else {...}
}
What am I missing?
The Invoke method excepts to receive a System.Delegate instance which can be invoked without passing any additional parameters. The delegate created by using DirectoryMonitor_ScanStarted requires 2 parameters and hence you get the exception when it's used.
You need to create a new delegate which wraps the call and arguments together.
MethodInvoker del = () => this.DirectoryMonitor_ScanStarted(sender,e);
Invoke(del);
You're missing the parameters:-
void DirectoryMonitor_ScanStarted(object sender, MonitorEventArgs e)
{
if (InvokeRequired)
{
Invoke(new EventHandler<MonitorEventArgs>(DirectoryMonitor_ScanStarted), sender, e);
}
else {...}
}
For reasons not clear to me (probably due to COM legacy) it's permissible to omit parameters when using a generic event, but not when using a user defined EventArg type.