C# 将单击事件添加到其他类中的按钮

C# 将单击事件添加到其他类中的按钮,c#,xamarin,xamarin.forms,C#,Xamarin,Xamarin.forms,我正在尝试将单击事件添加到另一个类中定义的按钮。 简单概述一下,这段代码创建了一堆卡片,上面有按钮,按钮需要点击事件 CardView类: public class CardView : ContentView { public Label Name { get; set; } public Image Photo { get; set; } public Label Location { get; set; } public Label Description

我正在尝试将单击事件添加到另一个类中定义的按钮。 简单概述一下,这段代码创建了一堆卡片,上面有按钮,按钮需要点击事件

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;

    }
public CardStackView()
{
RelativeLayout视图=新建RelativeLayout();
//创建一堆卡片
对于(int i=0;i
{
返回parent.Width;
}),
约束。RelativeToParent((父项)=>
{
返回父项高度;
})
);
}
this.BackgroundColor=Color.Azure;
这个。内容=视图;
}
在创建数据组时,是否可以向CardStackView构造函数中的CardView类(PassButton和FailButton)中的按钮添加单击事件/点击手势? 考虑到CardStackView其余部分的性质,需要在此处添加它们。有很多事情正在进行,在这一点上重新组织代码是不可行的。 甚至有可能做到这一点吗

还有我尝试过的东西。 我尝试使用for循环中的cardwiew实例访问按钮并添加事件,但这根本没有起到任何作用。 i、 e
card.PassButton.Clicked+=clickEvent

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

我们开始了

我认为
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公开你自己的事件

您可以在
cardwiew
类中创建自己的事件(或命令),并始终指定按钮的单击事件。像这样:

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

伙计!真是一团糟,哈?!我不知道你对什么感到困惑。card view类创建一张卡,card stack view创建多张卡。在创建卡片时,是否可以添加单击或点击事件?我知道了。我现在就回答。对不起,我正在努力学习英语。我提到它是因为这个解决方案在我看来非常复杂。尽管如此,我还是给出了一些可能性=)没问题!我很感谢你的意见。给我5分钟,我来执行这些。好的。让我知道它是否对你有用,或者我是否能在其他方面提供帮助(对不起,伙计,但这些似乎不起作用。我两次都试过了,但都没有成功。我在这两种方法中都进行了调试,还尝试在事件中使用断点,但它不会触发它们。您是否将button属性更改为variable?在第一种方法中,您将断点放在方法“
AddPassButtonClickedEvent
”中,它没有被命中?