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

时间:2012-03-23 12:17:56

标签: c# android button xamarin.android

对于 mono for android 来说,我绝对是初学者。

我已使用以下代码段以编程方式创建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);
            };

但是一个大问题这个代码在循环结束时,btn对象引用了最后一个按钮

因此,如果按下除最后一个按钮以外的任何按钮,则不会触发button click事件。 怎么解决? 理想情况下,它应该返回单击按钮的文本。

另外,请参阅下面的屏幕截图,默认按钮样式在这里看起来不太好。所以我想把它改成精确的矩形而不是round-rectangel(默认的)。 对此有何想法?

由于我对此非常陌生,所以我们将不胜感激!

修改

由于您的帮助,我能够适当地创建和引用所有按钮。

但如何将其样式设置为精确矩形?

screen

4 个答案:

答案 0 :(得分:2)

btn.Click += (sender, e)订阅移到for循环中。

更好 - 创建一个命名方法而不是创建许多匿名方法。例如。 Button_Click并订阅它:

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

在该方法中,您可以将发件人对象转换为Button,并知道单击了哪个按钮。

更新:这是完整的代码

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

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

我不想在代码中使用幻数:)

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);
}

答案 1 :(得分:1)

你的for循环操作一个按钮并且每次都创建一个新实例,但你的click事件只添加一次(它在你的for循环之外)。因此,它只会被添加到放入btn的最后一个Button实例(for循环中的最后一个按钮)。

您需要单独创建每个按钮(将它们放在List中),然后在for循环之外,您将获得每个按钮的引用,您可以单独将click事件添加到每个按钮。或者(更好的方式)在for循环中添加click事件,以便您创建的每个按钮都遵循它。请记住,由于事件将通过任意按钮(您的50个中的一个)到达,因此最好使用sender参数来确定其文本值。 即:

        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);
        };

答案 2 :(得分:1)

您已创建了50个按钮,因此您需要有50个引用。实现这一目标的最简单方法是创建一个按钮数组,如下所示:

       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);
            }
        }

//编辑:你还需要为每个按钮创建一个事件处理程序

答案 3 :(得分:-1)

这是因为你在for循环之外设置了按钮点击事件。把它放在里面,所以它被分配给每个按钮,而不仅仅是最后一个按钮。