查找动态添加的按钮点击监听器的调用者
Find caller of dynamically added button click's listener
我正在代码中添加一个按钮列表,我想为其添加点击侦听器。
我可以添加监听器,问题是我想知道调用监听器的按钮。
我试过下面的方法,但是传给监听器的值总是一样的:
foreach (...)
{
var button = (Button)GameObject.Instantiate(...);
packIndex++;
button.onClick.AddListener(() => this.OnButtonClick(packIndex));
}
public void OnButtonClick(int idx)
{
// idx is always the latest value in the above loop
}
TL;DR
如何从按钮点击侦听器中找到调用者?
试试这个
var button = (Button)GameObject.Instantiate(...);
packIndex++;
button.name = "Button" + packIndex;
button.onClick.AddListener(() => this.OnButtonClick(button));
public void OnButtonClick(Button button)
{
// idx is always the latest value in the above loop
}
你快搞定了。要存储索引,您需要通过在 for 循环内复制 packIndex
来 "capture" packIndex 变量。可以看看这个"closure in a for loop"现象很好的解释here.
以下代码应该有效:
foreach (...)
{
var button = (Button)GameObject.Instantiate(...);
packIndex++;
var packIndexCopy = packIndex;
button.onClick.AddListener(() => this.OnButtonClick(packIndexCopy));
}
public void OnButtonClick(int idx)
{
// idx is always the latest value in the above loop
}
请注意,@Nain 的回答也将起作用,因为在这种情况下,AddListener(() => this.OnButtonClick(button));
中的 "button" 对象引用每次在 foreach 循环中创建的新对象,因此编译器将将 OnButtonClick
处理程序正确绑定到该 'new' 副本。事实上,直接传递 Button
对象感觉更简洁一些,但这取决于您的其余代码。
如果你不熟悉闭包(这真的很令人困惑,需要很长时间才能理解!),this article 有很好的解释。
P.S。我写了一个小组件来测试这个,这里是 gist 以防它有帮助。
我正在代码中添加一个按钮列表,我想为其添加点击侦听器。
我可以添加监听器,问题是我想知道调用监听器的按钮。
我试过下面的方法,但是传给监听器的值总是一样的:
foreach (...)
{
var button = (Button)GameObject.Instantiate(...);
packIndex++;
button.onClick.AddListener(() => this.OnButtonClick(packIndex));
}
public void OnButtonClick(int idx)
{
// idx is always the latest value in the above loop
}
TL;DR
如何从按钮点击侦听器中找到调用者?
试试这个
var button = (Button)GameObject.Instantiate(...);
packIndex++;
button.name = "Button" + packIndex;
button.onClick.AddListener(() => this.OnButtonClick(button));
public void OnButtonClick(Button button)
{
// idx is always the latest value in the above loop
}
你快搞定了。要存储索引,您需要通过在 for 循环内复制 packIndex
来 "capture" packIndex 变量。可以看看这个"closure in a for loop"现象很好的解释here.
以下代码应该有效:
foreach (...)
{
var button = (Button)GameObject.Instantiate(...);
packIndex++;
var packIndexCopy = packIndex;
button.onClick.AddListener(() => this.OnButtonClick(packIndexCopy));
}
public void OnButtonClick(int idx)
{
// idx is always the latest value in the above loop
}
请注意,@Nain 的回答也将起作用,因为在这种情况下,AddListener(() => this.OnButtonClick(button));
中的 "button" 对象引用每次在 foreach 循环中创建的新对象,因此编译器将将 OnButtonClick
处理程序正确绑定到该 'new' 副本。事实上,直接传递 Button
对象感觉更简洁一些,但这取决于您的其余代码。
如果你不熟悉闭包(这真的很令人困惑,需要很长时间才能理解!),this article 有很好的解释。
P.S。我写了一个小组件来测试这个,这里是 gist 以防它有帮助。