Подтвердить что ты не робот

Кнопка Xamarin.Forms в ViewCell. Как обрабатывать событие?

У меня есть пользовательский ViewCell с кнопкой. Когда я нажимаю эту кнопку, я бы хотел обработать этот клик в ContentPage, который отображает ListView с ViewCells. В iOS я сделал бы это с делегатом из Cell. Как мне это сделать в С#/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);
        }
    }

Итак, все, что осталось сейчас, это получить фактический объект, связанный с ячейкой. В ItemSelected для ListView это делается следующим образом:

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

Как я могу сделать что-то вроде этого?


Получил! Это, возможно, не очень хорошее решение, но, похоже, это работает:

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

Я приму единственный ответ из-за того, что он подтолкнул меня в правильном направлении. (И это, вероятно, лучший способ сделать это).

4b9b3361

Ответ 1

Если вы используете модель представления или какой-либо другой класс, вы можете передать ее в свою ячейку и сделать свои звонки оттуда. В настоящее время представление списка также переопределяет кнопки в вашей ячейке с помощью события 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));

Таким образом вы можете инициировать свое событие из ячейки представления и обрабатывать его где-то еще (просмотреть модель).