I have four buttons like:
I also have a gameobject that attaches my script to it
Under the script I have one function, that should print the text of the button, when I use it in onClick() buttons.
Inspector
How to call one function on different buttons and print out the text of those buttons, that the user clicked?
Instead of passing the string to the callback function, it would make more sense to pass the Button instance itself. If you do this, you will be able to access more data from the Button if needed in the future.
public Button[] Btn;
void OnEnable()
{
//Register Button Events
for (int i = 0; i < Btn.Length; i++)
{
int btIndex = i;
Btn[i].onClick.AddListener(() => buttonCallBack(Btn[btIndex]));
}
}
private void buttonCallBack(Button buttonPressed)
{
Debug.Log(buttonPressed.GetComponentInChildren<Text>().text);
if (buttonPressed == Btn[0])
{
//Your code for button 1
}
if (buttonPressed == Btn[1])
{
//Your code for button 2
}
if (buttonPressed == Btn[2])
{
//Your code for button 3
}
if (buttonPressed == Btn[3])
{
//Your code for button 4
}
}
void OnDisable()
{
//Un-Register Button Events
for (int i = 0; i < Btn.Length; i++)
{
Btn[i].onClick.RemoveAllListeners();
}
}
If you still want to pass the Button text only:
public Button[] Btn;
void OnEnable()
{
//Register Button Events
for (int i = 0; i < Btn.Length; i++)
{
int btIndex = i;
string btText = Btn[btIndex].GetComponentInChildren<Text>().text;
Btn[i].onClick.AddListener(() => buttonCallBack(btText));
}
}
private void buttonCallBack(string buttonText)
{
Debug.Log(buttonText);
}
void OnDisable()
{
//Un-Register Button Events
for (int i = 0; i < Btn.Length; i++)
{
Btn[i].onClick.RemoveAllListeners();
}
}
Remember to assign your Buttons to the Btn variable slot in the Editor or you will get the null exception error.
Rather taking all the buttons in the list. Make a script Button.cs and give it to each UI buttons
In that script make one public method
public void OnButtonClickListener(int index) {
// Do your code here for button click using its index
}
now you just have to assign callbacks of each UI buttons to this public method and pass the argument of button's index.
I hope this will help you...
Related
I am using VS 2017 for an Visual C# application (.Net 4.6.2, 32 bit) that calls a form from the main form. In that second form the SelectedIndexChanged event is not firing for one of the ComboBoxes. Following is the code. If I have to register the event I don't know how. I originally had copied and pasted the ComboBoxes onto the form. Then I deleted that control and re-added the ComboBoxes from the ToolBox. Any help would be appreciated.
namespace Lottery_C_Sharp
{
public partial class Dialog_Matches_Input_Lotomania : Form
{
MatchesMethods_LM m;
public string[] lotomania_list = new string[10];
public string[] pick10_list = new string[5];
Utilities u;
public Dialog_Matches_Input_Lotomania(MatchesMethods_LM mm)
{
InitializeComponent();
m = mm;
u = new Utilities();
set_combos();
comboBox1.SelectedIndex = 0;
comboBox2.SelectedIndex = 0;
comboBox3.SelectedIndex = 0;
}
private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show("comboBox3_SelectedIndexChanged");
if (m.NumCurrLimit == 99)
{
set_lotomania_time_text();
set_lotomania_totals_text();
}
else
{
set_pick10_time_text();
set_pick10_totals_text();
}
}
public void set_combos()
{
set_lists();
comboBox1.Items.Clear();
comboBox2.Items.Clear();
comboBox3.Items.Clear();
if (m.NumCurrLimit == 99)
{
textBox1.Text = "Brazilian LotoMania";
AddToCombo(comboBox1, lotomania_list);
comboBox1.SelectedIndex = 0;
AddToCombo(comboBox2, lotomania_list);
comboBox2.SelectedIndex = 0;
AddToCombo(comboBox3, lotomania_list);
comboBox3.SelectedIndex = 0;
set_lotomania_time_text();
set_lotomania_totals_text();
}
else
{
textBox1.Text = "USA New York Pick 10";
AddToCombo(comboBox1, pick10_list);
comboBox1.SelectedIndex = 0;
AddToCombo(comboBox2, pick10_list);
comboBox2.SelectedIndex = 0;
AddToCombo(comboBox3, pick10_list);
comboBox3.SelectedIndex = 0;
set_pick10_time_text();
set_pick10_totals_text();
}
}
You should register the event for Your desired combobox in Designer properties, like this:
It generates event registration in Form1.Designer.cs (form name depends on how You've named it) auto-generated file:
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox3_SelectedIndexChanged);
Then Your function, where You can perform some actions when event occures shows in Form1.cs
private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
{
// Do something
}
You have several options to register the event.
Option 1:
Register in code:
public Dialog_Matches_Input_Lotomania(MatchesMethods_LM mm)
{
InitializeComponent();
...
comboBox1.SelectedIndexChanged += ComboBox_SelectedIndexChanged;
}
Option 2:
Double click on comboBox1 in the designer, this will automatically add and register an event.
Option 3:
Select the comboBox1 in the designer, right click and select "Properties", in the properties window select the event icon on top (the lightning symbol), find "SelectedIndexChanged" and enter the name of the event or double click to automatically add and register an event.
I am new here and I'm beginning my adventure with UNITY. I have problem with double click event. I'd like to buying or selling something in my shop. When I assign a button on unity (public Button button;) earlier it works. But when i try this change to button on Start and Update methods:
void Start () {
button = GameObject.Find(EventSystem.current.currentSelectedGameObject.name).GetComponent<Button>();
button.onClick.AddListener(ButtonListner);
}
void Update()
{
button = GameObject.Find(EventSystem.current.currentSelectedGameObject.name).GetComponent<Button>();
}
private void ButtonListner()
{
counter++;
if (counter == 1)
{
StartCoroutine("doubleClickEvent");
}
}
IEnumerator doubleClickEvent()
{
yield return new WaitForSeconds(clickTimer);
if (counter > 1)
{...}
the method doubleClickEvent() doesnt work unfortunately...
What shall I do? Regards ;)
First thing I noticed was: button = GameObject.Find(EventSystem.current.currentSelectedGameObject.name).GetComponent<Button>();
The EventSystem.current.currentSelectedGameObject property can be null at anytime especially in the first frame which means that using it in the Start function is not a good idea. Find the Button GameObject then get the Button component from it:
Button button;
void Start()
{
button = GameObject.Find("YourButtonName").GetComponent<Button>();
button.onClick.AddListener(ButtonListner);
}
Replace "YourButtonName" with the name of your Button GameObject.
You don't even need to do most of the stuff you did. You can get double click or click count with PointerEventData.clickCount from the OnPointerClick function. You must implement the IPointerClickHandler interface for this to work.
Simply attach to the Button GameObject:
public class ClickCountDetector : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
int clickCount = eventData.clickCount;
if (clickCount == 1)
OnSingleClick();
else if (clickCount == 2)
OnDoubleClick();
else if (clickCount > 2)
OnMultiClick();
}
void OnSingleClick()
{
Debug.Log("Single Clicked");
}
void OnDoubleClick()
{
Debug.Log("Double Clicked");
}
void OnMultiClick()
{
Debug.Log("MultiClick Clicked");
}
}
You can detect double click without a coroutine like the following:
// Choose the time you want between clicks to consider it a double click
float doubleClickTime = .2f, lastClickTime;
void Update()
{
// Checking left mouse button click, you could choose the input you want here
if (Input.GetMouseButtonDown(0))
{
float timeSinceLastClick = Time.time - lastClickTime;
if (timeSinceLastClick <= doubleClickTime)
Debug.Log("Double click");
else
Debug.Log("Normal click");
lastClickTime = Time.time;
}
}
I am creating a program where the user is pressing buttons like move 10 and move 1 to move a robot and when a user presses the button it will add a text in a listbox like "MoveRobot1" so when the user has finished pressing the buttons and presses the Play button, the program should go down the list line by line moving the robot based on the list at an interval of 300ms but I don't understand how to make it read line by line instead of all at once when I press Play.
private void BtnPlay_Click(object sender, EventArgs e)
{
this.WorkProgress += new WorkProgressHandler(DoWork);
_counter = 0;
this.robot.Reset();
this.MoveRobot(0);
string query1 = "MoveRobot(1)";
string query2 = "MoveRobot(10)";
for (int i = 0; i < MoveBox.Items.Count; i++)
{
if (MoveBox.Items[i].ToString() == query1)
{
this.MoveRobot(1);
DoWork();
}
if (MoveBox.Items[i].ToString() == query2)
{
this.MoveRobot(10);
DoWork();
}
}
}
private void DoWork()
{
_counter++; // increment the counter
}
Use Thread.Sleep in the end of every iteration :
for (int i = 0; i < MoveBox.Items.Count; i++)
{
if (MoveBox.Items[i].ToString() == query1)
{
this.MoveRobot(1);
DoWork();
}
if (MoveBox.Items[i].ToString() == query2)
{
this.MoveRobot(10);
DoWork();
}
Thread.Sleep(300);
}
i cant call or use event click of editor button that i create. the screen shot for the button is
the code that i make is like this
RepositoryItemComboBox repositoryItemComboBox1 = new RepositoryItemComboBox();
EditorButton lp = new EditorButton();
private void gridView1_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
{
repositoryItemComboBox1.Items.Clear();
GridView view = sender as GridView;
for (int i = 0; i < gridView1.RowCount; i++)
{
if (gridView1.GetDataRow(i) == null)
{
break;
}
string code = gridView1.GetDataRow(i)["code"].ToString();
if (!repositoryItemComboBox1.Items.Contains(code))
{
repositoryItemComboBox1.Items.Add(code);
}
}
if (e.Column.FieldName == "code" && view.IsFilterRow(e.RowHandle))
{
repositoryItemComboBox1.Buttons.Add(lp);
repositoryItemComboBox1.Buttons[0].Kind = DevExpress.XtraEditors.Controls.ButtonPredefines.Plus;
repositoryItemComboBox1.Buttons[1].Kind = DevExpress.XtraEditors.Controls.ButtonPredefines.Minus;
e.RepositoryItem = repositoryItemComboBox1;
}
when i click the minus nothing happen because no handler(event).
what i want is when i click that minus button it clear gridview filter
FYI : iam using devexpress
You can hook to the repositoryItem's ButtonClick event. In this event, you will know which button has been clicked. So let's say you create your button this way :
private void SomeMethod()
{
var buttonPlus = new DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Plus);
var buttonMinus = new DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Minus);
repositoryItemComboBox1.Buttons.Add(buttonPlus);
repositoryItemComboBox1.Buttons.Add(buttonMinus);
}
In the repositoryItemComboBox1_ButtonClick, you have access to the button properties in the "e" argument. In this example, i'm using the "Kind" property, but you could use the tag or anything really.
private void repositoryItemComboBox1_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
{
if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Minus)
{
// do something
}
else if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Plus)
{
// do something else
}
}
This is the way I do it.
I created a panel with a button "add" and a button "delete". If you click on "add" a panel is created right below this header, you can create as much as you want, they are listed.
On each panel there is a checkbox and I would like to delete the panel if the checkbox is checked once the button delete is clicked.
I can get the intuition of a loop : for, but still too novice to get through this without a little tip.
-
public partial class Test_auto : Form
{
ArrayList strategyFutureList = new ArrayList();
public Test_auto()
{
InitializeComponent();
Instance = this;
}
//Create a new future strategy
public void CreateStrategyFuture()
{
ConsoleStrategyItem strategyItemFuture = new ConsoleStrategyItem();
strategyItemFuture.Location = new Point(3, 3);
futureContainer.Height += 85;
strategyFutureList.Add(strategyItemFuture);
futureContainer.Controls.Add(strategyItemFuture);
ConsoleStrategyItem.Instance.txtStrategyName.Text = "Strat Future " + strategyFutureList.IndexOf(strategyItemFuture) + " ";
ConsoleStrategyItem.Instance.Name = "strategyFuture" + strategyFutureList.IndexOf(strategyItemFuture);
ConsoleStrategyItem.Instance.cbxDeleteStrategy.Name = "cbxDeleteFuture" + strategyFutureList.IndexOf(strategyItemFuture);
}
//Makes it appear
private void btnAddStrategyFuture_Click_1(object sender, EventArgs e)
{
CreateStrategyFuture();
}
//Delete a-some selected strategies
public void DeleteStrategyFuture()
{
for (int i = 0; i < strategyFutureList.Count; i++)
{
if (ConsoleStrategyItem.Instance.cbxDeleteStrategy.Checked = true)
{
}
}
}
private void btnDeleteStrategyFuture_Click(object sender, EventArgs e)
{
DeleteStrategyFuture();
}
}
you don't have to create a separate ArrayList to maintain the list of UserControls being added to the futureContainer, you can simply iterate through the Controls collection of it.
simply do this in your DeleteStrategyFuture() method
public void DeleteStrategyFuture()
{
var length=futureContainer.Controls.Count;
foreach(int i=0; i< length; i++)
{
if(futureContainer.Controls[i].GetType()==typeof(ConsoleStrategyItem))
{
bool isChecked =((ConsoleStrategyItem)futureContainer.Controls[i])
.Instance.cbxDeleteStrategy.Checked;
if(isChecked)
{
futureContainers.Controls.Remove(futureContainers.Controls[i]);
}
}
}
}