IDE : Visual Studio 2010 Express
Lib : Emgu CV 2.2
Level : Beginner
I've make Camera ON when Clicking PictureBox and viceversa, but it giving error :
Object reference not set to an instance of an object
Here the Event Handler :
private void pictureBoxCapture_Click(object sender, EventArgs e)
{
try
{
if (Clicked == true) //i dont know how to make it right
{
Application.Idle -= ProcessFrame;
}
else
{
Application.Idle += ProcessFrame;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Calling from :
private void ProcessFrame(object sender, EventArgs e)
{
//Cap = new Emgu.CV.Capture();
ImageFrame = Cap.QueryFrame();
pictureBoxCapture.Image = ImageFrame.ToBitmap();
}
how to set if else parameter likely, any advice?
Create a class level Boolean variable, then toggle it in your PictureBox's click event.
public partial class Form1 : Form
{
bool Clicked; //Create this Class level variable to be used in your handler
public Form1()
{
InitializeComponent();
}
private void pictureBoxCapture_Click(object sender, EventArgs e)
{
Clicked =! Clicked; //Toggle your Boolean here
try
{
if (Clicked)
{
Application.Idle -= ProcessFrame;
FaceDetect();
}
else
{
Application.Idle += ProcessFrame;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
I expect your error is not being thrown by the picturebox click event but the ProcessFrame() event. It will have the habit of firing once after you have removed the Application.Idle -= ProcessFrame; however there will be no image in the event argument to work with. Instead use this code as your ProcessFrame() event:
private void ProcessFrame(object sender, EventArgs e)
{
//Cap = new Emgu.CV.Capture();
ImageFrame = Cap.QueryFrame();
//Look for image content if null do nothing
if(ImageFrame != null)
{
pictureBoxCapture.Image = ImageFrame.ToBitmap();
//do any other operations on the image
}
}
Cheers,
Chris
Related
I have 18 buttons on the child form "Control Test" which send event to the parent form
Out of 18 buttons, 14 are ON and OFF functionality, making 7 pairs as in the picture
The problem is raising the event for each button, it causes very long and messy code, both in the child and the parent form,
Is there any less complex way to do it? like I have done with the menu.
Child Form:
Child Form:
// B Plus Relay On Button
public event EventHandler BPRElayOnBtnClicked;
protected virtual void WhenBPRelayOnBtnClicked(EventArgs e)
{
BPRElayOnBtnClicked.Invoke(this, e);
}
private void BPRelayOn_btn_Click(object sender, EventArgs e)
{
WhenBPRelayOnBtnClicked(e);
}
// B Plus Relay OFF Button
public event EventHandler BPRElayOffBtnClicked;
protected virtual void WhenBPRelayOffBtnClicked(EventArgs e)
{
BPRElayOnBtnClicked.Invoke(this, e);
}
private void BPRelayOff_btn_Click(object sender, EventArgs e)
{
WhenBPRelayOffBtnClicked(e);
}
// B Minus Relay ON Button
public event EventHandler BMRElayOnBtnClicked;
protected virtual void WhenBMRelayOnBtnClicked(EventArgs e)
{
BMRElayOnBtnClicked.Invoke(this, e);
}
private void BMRelayOn_btn_Click(object sender, EventArgs e)
{
WhenBMRelayOnBtnClicked(e);
}
// B Minus Relay OFF Button
public event EventHandler BMRElayOffBtnClicked;
protected virtual void WhenBMRelayOffBtnClicked(EventArgs e)
{
BMRElayOffBtnClicked.Invoke(this, e);
}
private void BMRelayOff_btn_Click(object sender, EventArgs e)
{
WhenBMRelayOffBtnClicked(e);
}
...... //event for each button
Parent Form:
private void viewToolStripMenuItem_Click(object sender, EventArgs e)
{
ToolStripMenuItem menu = sender as ToolStripMenuItem;
switch (menu.Name)
{
case "controlTestToolStripMenuItem":
if (Application.OpenForms["CtrlTest"] is CtrlTest ctrlTest)
{
ctrlTest.Focus();
return;
}
ctrlTest = new CtrlTest();
ctrlTest.BPRElayOnBtnClicked += CtrlTest_BPRElayOnBtnClicked;
ctrlTest.BPRElayOffBtnClicked += CtrlTest_BPRElayOffBtnClicked;
ctrlTest.BMRElayOnBtnClicked += CtrlTest_BMRElayOnBtnClicked;
ctrlTest.BMRElayOffBtnClicked += CtrlTest_BMRElayOffBtnClicked;
ctrlTest.PreRElayOnBtnClicked += CtrlTest_PreRElayOnBtnClicked;
ctrlTest.PreRElayOffBtnClicked += CtrlTest_PreRElayOffBtnClicked;
ctrlTest.MdiParent = this;
ctrlTest.Show();
break;
.........//Other menus ...
default:
break;
private void CtrlTest_BPRElayOnBtnClicked(object sender, EventArgs e)
{
//Do something here
}
private void CtrlTest_BPRElayOffBtnClicked(object sender, EventArgs e)
{
//Do something here
}
private void CtrlTest_BMRElayOnBtnClicked(object sender, EventArgs e)
{
//Do something here
}
private void CtrlTest_BMRElayOffBtnClicked(object sender, EventArgs e)
{
//Do something here
}
For the on/off, take a look at the following control. For the others setup one event and work out logic similar to the on/off buttons.
Download the source, add the class project to your Visual Studio solution. Open the class project and change the .NET Framework currently set to 4, to your project's .NET Framework version.
Setup an enum where for each on/off button set it's tag to one of the members. this ways things are clearer using a switch and enums.
public enum OperationType
{
BPlusRelay,
BMinusRelay,
PreRelay,
CycleCount,
PairDown,
TestMode,
StandbyMode
}
In the child form, setup and event and set tags for each on/off control. Change the names to reflect their purpose, I simply added them quickly for demoing purposes.
public partial class ChildForm : Form
{
public delegate void OnClicked(OperationType operationType, bool state);
public event OnClicked ClickedEvent;
public ChildForm()
{
InitializeComponent();
SetProperties();
}
public void SetProperties()
{
ToggleSwitch1.Tag = OperationType.BPlusRelay;
ToggleSwitch2.Tag = OperationType.BMinusRelay;
ToggleSwitch3.Tag = OperationType.PreRelay;
ToggleSwitch4.Tag = OperationType.CycleCount;
ToggleSwitch5.Tag = OperationType.PairDown;
ToggleSwitch6.Tag = OperationType.TestMode;
ToggleSwitch7.Tag = OperationType.StandbyMode;
var list = Controls.OfType<JCS.ToggleSwitch>().ToList();
foreach (var toggleSwitch in list)
{
toggleSwitch.CheckedChanged += ToggleSwitchOnCheckedChanged;
}
}
private void ToggleSwitchOnCheckedChanged(object sender, EventArgs e)
{
var current = (JCS.ToggleSwitch)sender;
ClickedEvent?.Invoke((OperationType)current.Tag, current.Checked);
}
}
In the main form, show the child form, subscribe to the event above.
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void ShowChildFormButton_Click(object sender, EventArgs e)
{
var childForm = new ChildForm();
childForm.ClickedEvent += ClickedEvent;
try
{
childForm.ShowDialog();
}
finally
{
childForm.Dispose();
}
}
private void ClickedEvent(OperationType operationType, bool state)
{
switch (operationType)
{
case OperationType.BPlusRelay:
// TODO
break;
case OperationType.BMinusRelay:
// TODO
break;
case OperationType.PreRelay:
// TODO
break;
case OperationType.CycleCount:
// TODO
break;
case OperationType.PairDown:
// TODO
break;
case OperationType.TestMode:
// TODO
break;
case OperationType.StandbyMode:
// TODO
break;
}
}
}
Partly done form, and note you can change the size of the buttons.
I'd like the activated event to only run once. I've tried using an If condition but the Reload variable doesn't set to false and thus it keeps looping endlessly. Is there a way around this?
Form1.cs code:
private void Form1_Activated(object sender, EventArgs e)
{
if (Class1.Reload == true) {
Class1.Reload = false;
}
}
Class1.cs code:
public class Class1 {
public static void Refresh() { Reload = true; }
public static bool Reload { get; set; }
Just unsubscribe from the event the first time it is triggered.
private void Form1_Activated(object sender, EventArgs e)
{
this.Activated -= Form1_Activated;
// Do other stuff here.
}
While CathalMF's solution is valid, I'll post the solution I implemented, whose aim was to refresh a DatagridView when I come back to the main form.
private void Form1_Activated(object sender, EventArgs e) {
if (Class1.Reload == true) {
Activated -= Form1_Activated;
Class1.Reload = false;
//Here I implement the code to refresh a DatagridView
Activated += Form1_Activated;
}
}
Class1.cs stays the same.
I am trying to implement a horizontal swipe event handler in the following app. However, the gr_CrossSliding cross sliding event handler never fires.
What do I need to do to fire gr_CrossSliding?
public sealed partial class MainPage : Page
{
private GestureRecognizer gr;
public MainPage()
{
this.InitializeComponent();
gr = new GestureRecognizer();
gr.GestureSettings = GestureSettings.CrossSlide;
gr.CrossSlideHorizontally = true;
gr.CrossSliding += gr_CrossSliding;
}
void gr_CrossSliding(GestureRecognizer sender, CrossSlidingEventArgs args)
{
// handle swipe event
}
}
You need to set the GestureRecognizer on the handlers of the UI Element that is getting the gestures.
In this case, I'm using a Grid (GrdFoto).
public MainPage()
{
this.InitializeComponent();
gestureRecognizer.GestureSettings = Windows.UI.Input.GestureSettings.Drag;
gestureRecognizer.Dragging += gestureRecognizer_Dragging;
GrdFoto.PointerPressed += GrdFoto_PointerPressed;
GrdFoto.PointerMoved += GrdFoto_PointerMoved;
GrdFoto.PointerReleased += GrdFoto_PointerReleased;
GrdFoto.PointerCanceled += GrdFoto_PointerCanceled;
}
void GrdFoto_PointerPressed(object sender, PointerRoutedEventArgs e)
{
this.gestureRecognizer.ProcessDownEvent(e.GetCurrentPoint(this.GrdFoto));
this.GrdFoto.CapturePointer(e.Pointer);
e.Handled = true;
}
void GrdFoto_PointerMoved(object sender, PointerRoutedEventArgs e)
{
this.gestureRecognizer.ProcessMoveEvents(e.GetIntermediatePoints(this.GrdFoto));
}
void GrdFoto_PointerReleased(object sender, PointerRoutedEventArgs e)
{
this.gestureRecognizer.ProcessUpEvent(e.GetCurrentPoint(this.GrdFoto));
e.Handled = true;
}
void GrdFoto_PointerCanceled(object sender, PointerRoutedEventArgs e)
{
this.gestureRecognizer.CompleteGesture();
e.Handled = true;
}
void gestureRecognizer_Dragging(GestureRecognizer sender, DraggingEventArgs args)
{
// Drag completed.
}
As I read in other questions, mostly peoples asks why it firing unexpectedly, but for me it never fires at all.
using System;
using System.Windows.Forms;
namespace TestDrag
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
treeView1.ItemDrag += treeView1_ItemDrag;
treeView1.DragLeave += treeView1_DragLeave;
groupBox1.AllowDrop = true;
groupBox1.DragEnter += groupBox1_DragEnter;
groupBox1.DragDrop += groupBox1_DragDrop;
treeView1.Nodes.Add("asd");
treeView1.Nodes.Add("dsa");
}
void groupBox1_DragDrop(object sender, DragEventArgs e)
{
throw new NotImplementedException();
}
void groupBox1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
{
treeView1.DoDragDrop(e.Item, DragDropEffects.Copy);
}
void treeView1_DragLeave(object sender, EventArgs e)
{
MessageBox.Show(this, "This message never shows when node dragged out of treeView1", "This is bad", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
I want to hide TreeView once item dragged out, but this event never occurs >_<
What could be the reason and how to fix or bypass this?
You have to make AllowDrop = True;
I have a form to ask for some data. At leaving of an input field (TextBox, DGV) the appropriate _Validating methode or _CellValueChanged methode is called.
If I want to end the program this methode is called, too - before the _FormClosing methode is called.
How can I fin out whether the program branches into the _FormClosing methode or not?
private void txb_Validating(object sender, CancelEventArgs e)
{
doLog("Text 1");
}
private void dgv_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
doLog("Text 2");
}
private void doLog(string txt)
{
// this is first called at closing...
if( [FormClosing is active] )
{
// Do something
}
else
{
// Do someting different
}
}
private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
// ... and this but later
// Write the Logfile
}
How have I to replace [FormClosing is active] to get to the right result?
I tried so
if ( this.FormClosing== true )
and so
this.FormClosing +=new FormClosingEventHandler(MyForm_FormClosing);
and so
FormClosingEventHandler cl = new FormClosingEventHandler(MyForm_FormClosing);
but I always was in a dead end.
This would do the trick:
public class YourForm : Form
{
private bool bIsClosing = false;
public YourClass()
{
InitializeComponent();
this.FormClosing +=
new FormClosingEventHandler(MyForm_FormClosing);
}
private void txb_Validating(object sender, CancelEventArgs e)
{
doLog("Text 1");
}
private void dgv_CellValueChanged(object sender,
DataGridViewCellEventArgs e)
{
doLog("Text 2");
}
private void doLog(string txt)
{
// this is first called at closing...
if( bIsClosing )
{
// Do something
}
else
{
// Do someting different
}
}
private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
bIsClosing = true;
// Write the Logfile
doLog("whatever");
}
}
this.FormClosing is an event that gets triggered once your form starts closing (like clicking the close button), hence the name. You need your application to register that event like so:
this.FormClosing +=new FormClosingEventHandler(MyForm_FormClosing);
This insures that once the FormClosing event gets triggered, your MyForm_FormClosing will be called.
You can create a flag like bool bIsFormClosing and set that flag once your closing function get called.
Edit:
As I understand now by reviewing your answer and your comments, you want to know in your doLog function if the form is closing.
Here is another approach
`
public class YourForm : Form
{
private bool bIsClosing = false;
Private bool bClosingHandled = false;
public YourClass()
{
InitializeComponent();
this.FormClosing +=
new FormClosingEventHandler(MyForm_FormClosing);
}
private void txb_Validating(object sender, CancelEventArgs e)
{
doLog("Text 1");
}
private void dgv_CellValueChanged(object sender,
DataGridViewCellEventArgs e)
{
doLog("Text 2");
}
private void doLog(string txt)
{
// this is first called at closing...
if( bIsClosing )
{
// Do something
bClosingHandled = true;
this.close();
}
else
{
// Do someting different
}
}
private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
If(!bClosingHandled)
{
bIsClosing = true;
e.Cancel = true;
return;
}
// Write the Logfile
doLog("whatever");
}
}`
This approach uses two flags... When you first receive a close event, you set the bIsClosing flag to true, cancels the event and return. Then once your dolog function get called, you force the close operation.