第六章:按钮点击(2)

分享按钮点击
如果一个程序包含多个Button视图,则每个Button都可以拥有自己的Clicked处理程序。 但是在某些情况下,多个Button视图共享一个常用的Clicked处理函数可能会更方便。
考虑一个计算器程序。 每个标记为0到9的按钮基本上都是一样的,并且对于这10个按钮有10个单独的Click处理程序 - 即使它们共享一些常用代码也没有多大意义。
您已经看到Clicked处理程序的第一个参数如何转换为Button类型的对象。 但你怎么知道它是哪个Button?
一种方法是将所有Button对象存储为字段,然后将使事件发生的Button对象与这些字段进行比较。
TwoButtons程序演示了这种技术。 这个程序类似于以前的程序,但有两个按钮 - 一个用于将Label对象添加到StackLayout,另一个用于删除它们。 两个Button对象存储为字段,以便Clicked处理程序可以确定哪一个触发了该事件:

public class TwoButtonsPage : ContentPage
{
    Button addButton, removeButton;
    StackLayout loggerLayout = new StackLayout();
    public TwoButtonsPage()
    {
        // Create the Button views and attach Clicked handlers.
        addButton = new Button
        {
            Text = "Add",
            HorizontalOptions = LayoutOptions.CenterAndExpand
        };
        addButton.Clicked += OnButtonClicked;
        removeButton = new Button
        {
            Text = "Remove",
            HorizontalOptions = LayoutOptions.CenterAndExpand,
            IsEnabled = false
        };
        removeButton.Clicked += OnButtonClicked;
        this.Padding = new Thickness(5, Device.OnPlatform(20, 0, 0), 5, 0);
        // Assemble the page.
        this.Content = new StackLayout
        {
            Children =
            {
                new StackLayout
                {
                    Orientation = StackOrientation.Horizontal,
                    Children =
                    {
                        addButton,
                        removeButton
                    }
                },
                new ScrollView
                {
                    VerticalOptions = LayoutOptions.FillAndExpand,
                    Content = loggerLayout
                }
            }
        };
    }
    void OnButtonClicked(object sender, EventArgs args)
    {
        Button button = (Button)sender;
        if (button == addButton)
        {
            // Add Label to scrollable StackLayout.
            loggerLayout.Children.Add(new Label
            {
                Text = "Button clicked at " + DateTime.Now.ToString("T")
            });
        }
        else
        {
            // Remove topmost Label from StackLayout.
            loggerLayout.Children.RemoveAt(0);
        }
        // Enable "Remove" button only if children are present.
        removeButton.IsEnabled = loggerLayout.Children.Count > 0;
    }
}

两个按钮都有一个HorizontalOptions值CenterAndExpand,以便它们可以通过使用水平StackLayout在屏幕顶部并排显示:
第六章:按钮点击(2)
请注意,当Clicked处理程序检测到removeButton时,它只是在Children属性上调用RemoveAt方法:

loggerLayout.Children.RemoveAt(0);

但是如果没有孩子会怎么样? 不会删除引发异常?
它不会发生! 当TwoButtons程序开始时,remove?按钮的IsEnabled属性被初始化为false。 当按这种方式禁用按钮时,模糊的外观会向用户发出信号,指示它不起作用。 它不会向用户提供反馈,并且不会触发点击事件。 在Clicked处理程序结束时,只有当loggerLayout至少有一个子项时,removeButton上的IsEnabled属性才会设置为true。
这说明了一个很好的通用规则:如果您的代码需要确定按钮Clicked事件是否有效,最好通过禁用该按钮来防止无效按钮点击。

上一篇:编程填空:第i位替换


下一篇:报错日志(长期更新)