Xamarin.Forms中的ViewCell按钮。如何处理事件?

14

我有一个带有按钮的自定义ViewCell。当我点击这个按钮时,我希望在显示ViewCells的ContentPage中处理此点击事件。在iOS中,我会使用来自单元格的委托来完成此操作。在C# / Xamarin.Forms中,我应该如何做?

这是我的自定义ViewCell:

    public CustomCell ()
    {
        button = new Button ();

        button.Text = "Add";
        button.VerticalOptions = LayoutOptions.Center;

        button.Clicked += [WHAT DO DO HERE???];

        var nameLabel = new Label ();
        nameLabel.SetBinding (Label.TextProperty, "name");
        nameLabel.HorizontalOptions = LayoutOptions.FillAndExpand;
        nameLabel.VerticalOptions = LayoutOptions.Center;

        var viewLayout = new StackLayout () {
            Padding = new Thickness (10, 0, 10, 0),
            Orientation = StackOrientation.Horizontal,
            Children = { nameLabel, button }
        };

        View = viewLayout;
    }

我的 ContentPage 使用此 ViewCell 的样子如下:

ListView.ItemTemplate = new DataTemplate (typeof(CustomCell));

那么,我该如何捕捉按钮按下的事件?

如果需要澄清,请提出。


好的,至少我已经做到了这一点:

这是我的 ContentPage:

    ...
    ListView.ItemTemplate = new DataTemplate (() => new CustomCell (CustomCellButtonClicked));
}

void CustomCellButtonClicked (CustomCell m, EventArgs e)
{
    //How do I get my associated object here?!

    System.Diagnostics.Debug.WriteLine ("Pressed cell " + m.ToString ());
}

这是我的手机:

    public EventArgs e = null;
    public event ButtonClickEvent ClickListener;
    public delegate void ButtonClickEvent (AddCardCell m, EventArgs e);

    public CustomCell (ButtonClickEvent Listener)
    {
        ClickListener += Listener;
        customButton = new Button ();

        customButton.Text = "Add";
        customButton.VerticalOptions = LayoutOptions.Center;

        customButton.Clicked += AddButtonClicked;

        ...
    }

    void AddButtonClicked (object sender, EventArgs e)
    {
        if (ClickListener != null) {
            ClickListener (this, e);
        }
    }

所以现在剩下的就是获取与单元格关联的实际对象。在 ListView 的 ItemSelected 中,可以像这样完成:

ListView.ItemSelected += async (object sender, SelectedItemChangedEventArgs e) => {
            var obj = (HSObject)e.SelectedItem;
        };

我该如何做类似这样的事情?


明白了!这也许不是一个好的解决方案,但它似乎可以工作:

void CustomCellButtonClicked (CustomCell m, EventArgs e)
{
    var myObject = m.BindingContext;
}

我会接受唯一的答案,因为它把我推向了正确的方向。(而且这可能是更好的方法)。


我也在寻找解决方案,但看起来似乎不可能。基本单元格对象无法访问页面对象,因此无法访问某些事件,如操作表和导航。您要处理哪个事件? - jcc
1个回答

21

如果您正在使用视图模型或其他类,您可以将其传递到您的单元格中并从那里进行调用。列表视图还会使用数据模板上的ItemSelected事件覆盖单元格上的按钮。幸运的是,他们在数据模板上放置了一个覆盖。

private readonly ViewModel _model;
public CustomCell (ViewModel model)
{
    _model = model; <--- Your DI foo
    BindingContext = model; <---

    button = new Button ();

    button.Text = "Add";
    button.VerticalOptions = LayoutOptions.Center;

    button.Clicked += (sender, args) => _model.DoSomething(); <---- Your action

    var nameLabel = new Label ();
    nameLabel.SetBinding (Label.TextProperty, "name");
    nameLabel.HorizontalOptions = LayoutOptions.FillAndExpand;
    nameLabel.VerticalOptions = LayoutOptions.Center;

    var viewLayout = new StackLayout () {
        Padding = new Thickness (10, 0, 10, 0),
        Orientation = StackOrientation.Horizontal,
        Children = { nameLabel, button }
    };

    View = viewLayout;
}

然后,您可以使用匿名函数将您的类/视图模型传递到您的单元格中。

ListView.ItemTemplate = new DataTemplate (() => new CustomCell(viewModel));

通过这种方式,您可以从视图单元格触发事件,并在其他地方(视图模型)处理它。


1
谢谢!你上次的代码行让我朝着正确的方向前进了。你能否检查一下我的更新答案,并帮我解决最后一个问题?谢谢。 - ullstrm
我已经接受了你的答案,尽管我没有使用它。 - ullstrm
谢谢你的代码片段。它帮我省去了ListView.ItemTemplate = new DataTemplate (() => new CustomCell(viewModel));这一步。 - PEO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接