简体   繁体   English

引用以编程方式创建的按钮及其点击事件

[英]Referring to programmatically created button and it's click event

I'm absolute beginner when it comes to mono for android . 我绝对是android的初学者。

I've used following code snippet to create 50 buttons programmatically: 我使用以下代码片段以编程方式创建50个按钮:

for(int i=0;i<50;i++)
            {
            //code to calculate x and y position
                btn=new Button(this);
                //btn.SetBackgroundColor(Android.Resource.Color.);
                btn.SetTextSize(Android.Util.ComplexUnitType.Sp,8);
                btn.Text="Scrip "+i+"\n"+"CMP "+i+"\n"+"%Chg "+i;
                lp = new RelativeLayout.LayoutParams(new ViewGroup.MarginLayoutParams((width+30)/5, (height-10)/10));
                btn.LayoutParameters=lp;
                lp.SetMargins(leftMargin,topMargin, 0, 0);
                main.AddView(btn);
            }

            String str="";
            btn.Click += (sender, e) => 
            {
                str=btn.Text;
                Toast.MakeText(this, "Selected="+str,ToastLength.Short).Show();
                Console.WriteLine("Selected="+str);
            };

But one big problem with this code is at the end of the loop, btn object has reference of the last button only . 但是此代码的一个大问题是循环结束时, btn对象引用了最后一个按钮。

So if any button other than last button is pressed, button click event is not fired. 因此,如果按下了除最后一个按钮以外的任何按钮,则不会触发button click事件。 How to resolve it? 怎么解决呢? Ideally, it should return the text of the clicked button. 理想情况下,它应该返回所单击按钮的文本。

Also, referring to below screenshot, the default button style doesn't look good here. 另外,参考下面的屏幕截图,默认按钮样式在这里看起来不太好。 So I want to change it to exact rectangle and not rounded-rectangel(the default one). 因此,我想将其更改为确切的矩形,而不是圆角矩形(默认值)。 Any idea on this? 有什么想法吗?

As I'm very new to this, any help will be appreciated !! 因为我对此很陌生,所以我们将不胜感激!

EDIT 编辑

Asa result of your help, I'm able to create and refer all buttons appropriately. 在您的帮助下,我能够适当地创建和引用所有按钮。

But how to set their style as exact rectangle?? 但是如何将其样式设置为确切的矩形呢?

屏幕

Move btn.Click += (sender, e) subscription inside for loop. btn.Click += (sender, e)移动到for循环内的btn.Click += (sender, e)订阅中。

Even better - create one named method instead of creating many anonymous. 甚至更好-创建一个命名方法,而不是创建许多匿名方法。 Eg Button_Click and subscribe to it: 例如,Button_Click并订阅它:

btn = new Button(this);
btn.Click = Button_Click;

Inside that method you can cast sender object to Button and know which button was clicked. 在该方法内,您可以将发送方对象强制转换为Button,并知道单击了哪个按钮。

UPDATE: here is complete code 更新:这是完整的代码

const int rowsCount = 10;
const int columnsCount = 5;
int buttonsCount = rowsCount * columnsCount;

for (int i = 0; i < buttonsCount; i++)            
    AddButton();

I prefer not to use magic numbers in code :) 我不想在代码中使用幻数:)

private void AddButton()
{
    Button button = new Button(this);
    button.Click += Button_Click;
    // add text and other properties
    main.AddView(button);
}

private void Button_Click(object sender, EventArgs e)
{
    Button button = (sender as Button);
    // use clicked button e.g. Console.WriteLine("Selected = {0}", button.Text);
}

Your for loop operates on a button and creates a new instance of it every time, but your click event is only added once (it is outside your for loop). for循环在按钮上操作并每次创建一个新实例,但是click事件仅添加一次(它在for循环之外)。 Therefore it will only be added to the last instance of Button that is put into btn (the last button from the for loop). 因此,它只会添加到btn中最后一个Button实例(for循环中的最后一个按钮)中。

You need to either create each button separately (putting them in a List say) and then outside the for loop you will have a reference to each that you can add the click event to each button individually. 您需要分别创建每个按钮(将它们放入“列表”中),然后在for循环之外,您将获得对每个按钮的引用,可以将click事件分别添加到每个按钮。 Or ( the much better way ) add the click event inside the for loop, so that each button you create adheres to it. 或者( 更好的方法 )在for循环中添加click事件,以使您创建的每个按钮都遵守该事件。 Bear in mind that since the event will then be reached by an arbitrary button(one of your 50) that it will be best to use the sender parameter to determine its text value. 请记住,由于该事件将通过任意按钮(您的50个按钮中的一个)到达,因此最好使用sender参数确定其文本值。 ie: 即:

        btn.Click += (sender, e) => 
        {
            Button b = sender as Button;
            if ( b == null ) return;
            String str;
            str=b.Text;
            Toast.MakeText(this, "Selected="+str,ToastLength.Short).Show();
            Console.WriteLine("Selected="+str);
        };

You have created 50 buttons, so you need to have 50 references to it. 您已经创建了50个按钮,因此需要50个引用。 The easiest way to achieve this is to create an array of buttons, like so: 实现此目的的最简单方法是创建按钮数组,如下所示:

       Button[] btns = new Button[50];
       for(int i=0;i<50;i++)
       {
            {
            //code to calculate x and y position
                btns[i]=new Button(this);
                //btn.SetBackgroundColor(Android.Resource.Color.);
                btns[i].SetTextSize(Android.Util.ComplexUnitType.Sp,8);
                btns[i].Text="Scrip "+i+"\n"+"CMP "+i+"\n"+"%Chg "+i;
                lp = new RelativeLayout.LayoutParams(new ViewGroup.MarginLayoutParams((width+30)/5, (height-10)/10));
                btns[i].LayoutParameters=lp;
                lp.SetMargins(leftMargin,topMargin, 0, 0);
                main.AddView(btn);
            }

            btns[i].Click += (sender, e) => 
            {
                String str= ( (sender as Button) != null) ? (sender as Button).Content.ToString() : "";
                Toast.MakeText(this, "Selected="+str,ToastLength.Short).Show();
                Console.WriteLine("Selected="+str);
            }
        }

//EDIT: You'll also need to create an eventhandler for each button //编辑:您还需要为每个按钮创建一个事件处理程序

it's because you are setting the button click event outside the for loop. 这是因为您要在for循环之外设置按钮单击事件。 put it on the inside so it gets assigned to every button, not just the last one. 将其放在里面,以便将其分配给每个按钮,而不仅仅是最后一个按钮。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM