将Click事件添加到不同类中的按钮

时间:2017-11-01 10:46:49

标签: c# xamarin xamarin.forms

我正在尝试将click事件添加到在不同类中定义的按钮。 只需快速浏览一下,这段代码会创建一堆带有按钮的卡片,按钮需要点击事件。

CardView类:

public class CardView : ContentView
{
    public Label Name { get; set; }
    public Image Photo { get; set; }
    public Label Location { get; set; }
    public Label Description { get; set; }
    public Button PassButton { get; set; }
    public Button FailButton { get; set; }


    public CardView()
    {
        // gives the card its black line
        Grid grid = new Grid();
        grid.BackgroundColor = Color.Black;
        grid.Padding = 2;

        RelativeLayout view = new RelativeLayout();


        // box view as the background
        BoxView boxView1 = new BoxView
        {
            Color = Color.White,
            InputTransparent = true

        };

        view.Children.Add(boxView1,
            Constraint.Constant(0), Constraint.Constant(0),
            Constraint.RelativeToParent((parent) => {
                return parent.Width;
            }),
            Constraint.RelativeToParent((parent) => {
                return parent.Height;
            })
        );


        // items image
        Photo = new Image()
        {
            InputTransparent = true,
            Aspect = Aspect.Fill
        };

        view.Children.Add(Photo,
            Constraint.Constant(0),
            Constraint.RelativeToParent((parent) =>
            {
                double h = parent.Height * 0.80;
                return ((parent.Height - h) / 2) + 20;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return (parent.Height * 0.40);
            })
        );

        // items label
        Name = new Label()
        {
            TextColor = Color.Black,
            FontSize = 22,
            InputTransparent = true,
            FontAttributes = FontAttributes.Bold,
            HorizontalOptions = LayoutOptions.CenterAndExpand,
            HorizontalTextAlignment = TextAlignment.Center
        };

        view.Children.Add(Name,
            Constraint.Constant(10), Constraint.Constant(10),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width;
            }),
            Constraint.Constant(28)
        );           

        // location description
        Location = new Label()
        {
            TextColor = Color.Black,
            FontSize = 18,
            InputTransparent = true
        };

        view.Children.Add(Location,
            Constraint.Constant(30), Constraint.Constant(40),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width;
            }),
            Constraint.Constant(28)
        );

        //Image[] stars = new Image[5];

        StackLayout stack = new StackLayout
        {
            Orientation = StackOrientation.Horizontal,
            Spacing = 2
        };         

        view.Children.Add(stack,
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width - 90; // 
            }),
            Constraint.Constant(40)); //40

        // bottom label
        Description = new Label()
        {
            TextColor = Color.Black,
            FontSize = 16,
            FontAttributes = FontAttributes.None,
            HorizontalOptions = LayoutOptions.CenterAndExpand,
            HorizontalTextAlignment = TextAlignment.Center,
            InputTransparent = true
        };

        view.Children.Add(
            Description,
            Constraint.Constant(0),
            Constraint.RelativeToParent((parent) =>
            {
                return (parent.Height / 2f) + 30;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width;
            }),
            Constraint.Constant(40)
        );

        // camera button
        Button camera = new Button()
        {
            Text = "Camera",

            InputTransparent = true
        };

        view.Children.Add(camera,
                Constraint.RelativeToParent((parent) =>
                {
                    return (parent.Width / 2f) - (camera.Width / 2f);
                }),
                Constraint.RelativeToParent((parent) =>
                {
                    return parent.Height - 70;
                })
                );



        PassButton = new Button()
        {
            Text = "Pass",
        };

        view.Children.Add(PassButton,Constraint.RelativeToParent((parent)=> 
                                    {
                                        return (parent.Width / 8f) - (PassButton.Width / 4f);
                                    }),
                                    Constraint.RelativeToParent((parent) =>
                                    {
                                        return parent.Height - 70;
                                    })                                        
                                    );

        FailButton = new Button()
        {
            Text = "Fail",
        };


        view.Children.Add(FailButton, Constraint.RelativeToParent((parent) =>
        {
            return (parent.Width *(3/ 4f)) - (FailButton.Width / 4f);
        }),
        Constraint.RelativeToParent((parent) =>
        {
            return parent.Height - 70;
        })
        );


        grid.Children.Add(view);

        Content = grid;
    }
}

此类用作整个套牌的模板。 在另一个类中,创建了CardView类的多个实例来制作卡片组。 卡的创建工作正常。

所以在CardStackView(在构造函数中)创建了套牌:

 public CardStackView()
    {
        RelativeLayout view = new RelativeLayout();

        // create a stack of cards
        for (int i = 0; i < NumCards; i++) // 
        {
            var card = new CardView();                
            cards[i] = card;
            card.InputTransparent = true;
            card.IsVisible = false;


            view.Children.Add(
                card,
                Constraint.Constant(0),
                Constraint.Constant(0),
                Constraint.RelativeToParent((parent) =>
                {
                    return parent.Width;
                }),

                Constraint.RelativeToParent((parent) =>
                {
                    return parent.Height;
                })
            );
        }

        this.BackgroundColor = Color.Azure;

        this.Content = view;

    }

在创建卡座时,是否可以在CardStackView的构造函数中将Click事件/ tapgest添加到CardView类(PassButton和FailButton)中的按钮? 考虑到CardStackView其余部分的性质,它们需要添加。有很多事情发生,此时重新组织代码是不可行的。 甚至可以这样做吗?

我也尝试过的东西。 我尝试在for循环中使用CardView的实例来访问按钮并添加事件,但这根本没有做任何事情。 即card.PassButton.Clicked += clickEvent

有什么想法吗?或者即使有可能吗?

1 个答案:

答案 0 :(得分:1)

我们走了。

我认为CardView中的按钮,标签和图像可以是私有变量,因此您可以以更加可控的方式处理它(外部类不应该更改卡内按钮的位置,例如)

有很多方法可以做到这一点。给出了代码结构,我想了两种方法:

- 1封装事件处理程序定义

您可以在CardView中创建一个方法,例如:

public class CardView : ContentView
{
    // Your stuffs

    public void AddPassButtonClickedEvent(EventHandler handler)
    {
        if(handler != null)
            PassButton.Clicked += handler;
    }

    // Your stuffs
}

课外,您将使用它:

var cardView = new CardView();
cardView.AddPassButtonClickedEvent((sender, args) => 
{
    // Do something
});

- 2公开您自己的活动

您可以在CardView课程中创建自己的事件(或命令),并始终将按钮的单击事件设为对齐。像这样:

public class CardView : ContentView
{
    // Your stuffs

    public event EventHandler MyPassButtonClickedEvent;

    public CardView()
    {
        // Instantiate your PassButton
        PassButton.Clicked += OnPassButtonClicked;
    }

    protected void OnPassButtonClicked(object sender, EventArgs args)
    {
        MyPassButtonClickedEvent?.Invoke(object, args);
    }

    // Your stuffs
}

同样,您可以通过这种方式使用它:

class Fake
{
    CardView cardView;

    public Fake()
    {
        cardView = new CardView();
        cardView.MyPassButtonClickedEvent += MyHandler;
    }

    void MyHandler(object sender, EventArgus args)
    {
        // Do something
    }
}