I have a custom control (UserControl) that contains two labels and a button, I load this control dynamically in a form. When I click on the custom control button, I would like to get the information contained for example in the label1 of the custom control.
private void mycustomcontrol_MouseClick(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
mycustomcontrol = sender as mycustomcontrol;
MessageBox.Show(mycustomcontrol.Info); // <-- mycustomcontrol.Info refers to the label1 text on the custom control
}
}
In my Usecontrol:
public new event MouseEventHandler MouseClick
{
add
{
button1.MouseClick += value;
}
remove
{
button1.MouseClick -= value;
}
}
I get an exception:
System.NullReferenceException: 'Reference to an object not set to an object instance.'
unorthodox solution, but in my case it's fine:
In my UserControl:
public static string _value{ get; set; }
private void Button1_MouseClick(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
_value = lbl_info.Text;
}
}
In my Form:
private void mycustomcontrol_MouseClick(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
MessageBox.Show(mycustomcontrol._value);
}
}
Related
I have a WinForm, and add a UserControl with a DataGridView.
Now I want to do a doubleClick on the DataGridView and get the object data to my Form.
In my UserControl:
public event DataGridViewCellEventHandler dg_CellDoubleClickEvent;
private void dg_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex != -1)
{
try
{
Cursor.Current = Cursors.WaitCursor;
Address a = dg.Rows[e.RowIndex].DataBoundItem as Address;
if (a != null)
{
// how can I pass my Address object??
dgAngebote_CellDoubleClickEvent?.Invoke(this.dgAngebote, e);
}
}
finally { Cursor.Current = Cursors.Default; }
}
}
In my Form:
private void FormAddress_Load(object sender, EventArgs e)
{
uc.dg_CellDoubleClickEvent += new DataGridViewCellEventHandler(myEvent);
}
private void myEvent(object sender, DataGridViewCellEventArgs e)
{
MessageBox.Show("test");
}
My MessageBox is shown. This is ok, but I want to geht my Address to show.
Is this the right way of doing that? How?
Kind regards.
You can change the delegate to one you define or use the generic form of System.Action. There is also the option to use EventHandler and define your own event args class that you can add properties and logic to.
Below is an example using the Action delegate, with T being your Address type.
public event Action<Address> OnAddressSelected;
...
Address address = dg.Rows[e.RowIndex].DataBoundItem as Address;
if (address != null)
{
OnAddressSelected?.Invoke(address);
}
And in the form
private void FormAddress_Load(object sender, EventArgs e)
{
uc.OnAddressSelected += OnAddressSelected;
}
private void OnAddressSelected(Address address)
{
MessageBox.Show($"Address: {address}");
}
I need to get the sender of the mouseDown event from within the event and set it as a global variable to use in a dragDrop event, so that it calls a method depending on what picturebox was dragged. I need the control name or something. My attempt:
Global variable "dragSource":
public partial class MapDesignerView : Form
{
public Map myMap { get; set; }
public MapController myMapController { get; set; }
public MapConstructor myMapConstructor { get; set; }
public MouseEventHandler myDetectMouse { get; set; }
object dragSource = null;
mouseDown
private void pbxMinotaur_MouseDown(object sender, MouseEventArgs e)
{
pbxMap.AllowDrop = true;
pbxMinotaur.DoDragDrop(pbxMinotaur.Name, DragDropEffects.Copy |
DragDropEffects.Move);
dragSource = sender;
}
DragDrop
private void pbxMap_DragDrop(object sender, DragEventArgs e)
{
{
if (dragSource == pbxMinotaur)
{
myDetectMouse.setMinotaur(e, myMap.myCells);
}
So what exactly isn't working... the only thing I can think that might be causing the problem is that you're storing the reference to the entire control in your drag source.
A better idea might be to just story the Id. and then test it based on the Id further down.
string dragSourceName = null;
private void pbxMinotaur_MouseDown(object sender, MouseEventArgs e)
{
pbxMap.AllowDrop = true;
pbxMinotaur.DoDragDrop(pbxMinotaur.Name, DragDropEffects.Copy |
DragDropEffects.Move);
Control c = (sender as Control);
if(c != null)
dragSourceName = c.Name;
}
private void pbxMap_DragDrop(object sender, DragEventArgs e)
{
if (dragSourceName == pbxMinotaur.Name)
{
myDetectMouse.setMinotaur(e, myMap.myCells);
}
I have a timer event as given below and I have got some suggestions from this post. Could you suggest me what is wrong with this? I am getting the following crash:
Unable to cast object of type System.Windows.Forms.Timer to type System.Windows.Forms.Button.
Any suggestions on where I am going wrong??
public MainForm()
{
InitializeComponent();
ButtonTimer.Tick += new EventHandler(ButtonTimer_Tick);
ButtonTimer.Interval = 100;
}
private void ButtonTimer_Tick(object sender, EventArgs e)
{
Button CurrentButton = (Button)sender;
string PressedButton = CurrentButton.Name;
switch (PressedButton)
{
case "BoomUp":break;
}
}
private void BoomUp_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//ButtonTimer.Enabled = true;
ButtonTimer.Start();
}
}
private void BoomUp_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ButtonTimer.Stop();
}
}
You have a problem in ButtomTime_Tick method :
Button CurrentButton = (Button)sender;
sender is not a Button, it's a Timer.
So what you gonna do now ?
You could add a private field in your class
private Button currentButton_;
and
private void BoomUp_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
currentButton_ = e.Button;//but I don't know if e.Button has a Name "BoomUp"
//you can set the name manually if needed :
currentButton_.Name = "BoomUp";
//ButtonTimer.Enabled = true;
ButtonTimer.Start();
}
}
and
private void ButtonTimer_Tick(object sender, EventArgs e)
{
switch (currentButton_.Name)
{
case "BoomUp":break;
}
}
In ButtonTimer_Tick the sender is the timer, not a button. Hence you cast a timer into a button (1st line in that method).
I thought we should raise an event
This is what I have found:
event OnButtonClicked ()EventArgs;
HTMLButtonClickEventArgs:EventArgs
{
String ButtonName;
}
I am doing a web Browser control and this is the code I wrote for its button clicked,but I want to know on which button user clicks:
public delegate void ButtonPressedEventHandler(object sender, EventArgs e);
public event ButtonPressedEventHandler ButtonPressed;
void OnButtonPressed()
{
if (ButtonPressed != null)
ButtonPressed(this, new EventArgs());
}
I write an example for you:try this:
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.DocumentText = "<html><body><button id=\"btn1\" type=\"button\">Click Me!</button><button id=\"btn2\" type=\"button\">Click Me!</button></body></html>";
}
Call Click event:
//Edited
bool First_Call = true;
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (First_Call)
{
webBrowser1.Document.Click += new HtmlElementEventHandler(Document_Click);
First_Call = false;
}
}
Get Active Element When User click on document but
void Document_Click(object sender, HtmlElementEventArgs e)
{
// **Edited**
//Check Element is Button
if (webBrowser1.Document.ActiveElement.TagName == "BUTTON")
{
MessageBox.Show(webBrowser1.Document.ActiveElement.Id);
}
}
I have a few text boxes on my UI that I want to display the mobile keyboard for when the control has focus, then go away.
Note: for this particular program, it is a tall screen and has no physical keyboard on the device.
Add an InputPanel to your Form, hook up the GotFocus and LostFocus events of the TextBox and show/hide the input panel in the event handlers:
private void TextBox_GotFocus(object sender, EventArgs e)
{
SetKeyboardVisible(true);
}
private void TextBox_LostFocus(object sender, EventArgs e)
{
SetKeyboardVisible(false);
}
protected void SetKeyboardVisible(bool isVisible)
{
inputPanel.Enabled = isVisible;
}
Update
In response to ctacke's request for completeness; here is sample code for hooking up the event handlers. Normally I would use the designer for this (select the textbox, show the property grid, switch to the event list and have the environment set up handlers for GotFocus and LostFocus), but if the UI contains more than a few text boxes you may wish to have it more automated.
The following class exposes two static methods, AttachGotLostFocusEvents and DetachGotLostFocusEvents; they accept a ControlCollection and two event handlers.
internal static class ControlHelper
{
private static bool IsGotLostFocusControl(Control ctl)
{
return ctl.GetType().IsSubclassOf(typeof(TextBoxBase)) ||
(ctl.GetType() == typeof(ComboBox) && (ctl as ComboBox).DropDownStyle == ComboBoxStyle.DropDown);
}
public static void AttachGotLostFocusEvents(
System.Windows.Forms.Control.ControlCollection controls,
EventHandler gotFocusEventHandler,
EventHandler lostFocusEventHandler)
{
foreach (Control ctl in controls)
{
if (IsGotLostFocusControl(ctl))
{
ctl.GotFocus += gotFocusEventHandler;
ctl.LostFocus += lostFocusEventHandler ;
}
else if (ctl.Controls.Count > 0)
{
AttachGotLostFocusEvents(ctl.Controls, gotFocusEventHandler, lostFocusEventHandler);
}
}
}
public static void DetachGotLostFocusEvents(
System.Windows.Forms.Control.ControlCollection controls,
EventHandler gotFocusEventHandler,
EventHandler lostFocusEventHandler)
{
foreach (Control ctl in controls)
{
if (IsGotLostFocusControl(ctl))
{
ctl.GotFocus -= gotFocusEventHandler;
ctl.LostFocus -= lostFocusEventHandler;
}
else if (ctl.Controls.Count > 0)
{
DetachGotLostFocusEvents(ctl.Controls, gotFocusEventHandler, lostFocusEventHandler);
}
}
}
}
Usage example in a form:
private void Form_Load(object sender, EventArgs e)
{
ControlHelper.AttachGotLostFocusEvents(
this.Controls,
new EventHandler(EditControl_GotFocus),
new EventHandler(EditControl_LostFocus));
}
private void Form_Closed(object sender, EventArgs e)
{
ControlHelper.DetachGotLostFocusEvents(
this.Controls,
new EventHandler(EditControl_GotFocus),
new EventHandler(EditControl_LostFocus));
}
private void EditControl_GotFocus(object sender, EventArgs e)
{
ShowKeyboard();
}
private void EditControl_LostFocus(object sender, EventArgs e)
{
HideKeyboard();
}
Use the InputPanel class. Enable it when you get focus, disable it when you lose focus.