Передача параметра из кнопки в ListView во ViewModel

266
28 января 2019, 23:20

Товарищи, подскажите, как во ViewModel передать параметр кликнутой кнопки? в хамл прописан биндинг на комманду, кнопка во вью модел вызывается, но вот не могу сообразить, как понять, какая кнопка была нажата? У меня несколько кнопок, под каждым товаром с надписью добавить в корзину.

Проверил, работу команд и самой модели ViewModel , работает, если кнопка находится во вне ListView, А если кнопка внутри ListView почему не работает команда.

Пробовал во View к BindingContext присваивать и к контенту и к переменой ListView, все равно не реагирует.

И соответсвенно когда команда сама заработает, будет видно, передастся ли параметр, по которому был клик

Подскажите пожалуйста, в чем может быть проблема?

Код класса View

 public ObservableCollection<ItemLPH> ItemsListKategory { get; set; }
    public ItemKategorView (KorzinaViewModel KVM, ItemsLPH LPH, KategoryItem.TypeItem typeItem)
    {
        InitializeComponent();
        BindingContext = KVM;
        MyListViewKategor.BindingContext = KVM;
        ItemsListKategory = LPH.GetKategoryList(typeItem);
        MyListViewKategor.ItemsSource = ItemsListKategory;
    }

Код XAML

<ContentPage.Content >
    <StackLayout Padding="5">
        <ListView x:Name="MyListViewKategor"
                  ItemTapped="MyListViewKategor_ItemTapped"
                  HasUnevenRows="True"
                  >
                <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout  Orientation="Horizontal"  BackgroundColor="White" >
                            <StackLayout WidthRequest="160" HeightRequest="120"  Padding="10">
                                <Image Source="{Binding ImageName}"   />
                            </StackLayout>                                
                            <StackLayout >
                                <Label  Text="{Binding Name}"  />
                                <Label Text="{Binding CountOneitem}" />
                                <Label Text="{Binding Rub}" />
                                <Button  Text="В корзину"  Command="{Binding AddDelCommand}" CommandParameter="{Binding CurrentItem}"/>
                            </StackLayout>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <StackLayout> <!-- тест стек находится под листвью -->
            <Label Text="{Binding Message}"/>
            <Button  Text="В корзину"  Command="{Binding AddDelCommand}"/>
        </StackLayout>
    </StackLayout>
</ContentPage.Content>

Код Страницы ViewModel

 public class KorzinaViewModel : BaseViewModel
{
    public IKorzinaModel korzinaModel;
    //////////////
    ///????
    private ItemLPH _currenItem;//Храним выбраный итем      
    public ItemLPH CurrentItem// Биндинг события клика добавления в корзину
    {
        get { return _currenItem; }
        set
        {
            _currenItem = value;
            if (_currenItem == null) return;
            // заносим в корзину выбранный товар
            korzinaModel.AddItem(_currenItem);
            NotifyPropertyChanged(nameof(TotalSumm));// обновляем(перерисовываем) общую сумму покупки
            _currenItem = null;
        }
    }
    public KorzinaViewModel()//конструктор
    {
        this.korzinaModel = new KorzinaModel();
    }

    private string _message = "default text";
    public string Message
    {
        get { return _message; }
        set
        {
            _message = value;
            NotifyPropertyChanged(nameof(Message));
        }            
    }

    public ICommand AddDelCommand
    {
        get
        {
            return new Command(() =>
            {
                Message = "клик";
            }
                );
        }
    }
}
Answer 1

Чтобы все заработало, Вам необходимо внести минимальные изменения.

В XAML:

В шаблоне ItemTemplate, чтобы биндинг команды был к ViewModel, необходимо указать Source, иначе биндинг будет к Вашей модели. В CommandParameter достаточно указать {Binding .}

Следовательно, заменить

<Button  Text="В корзину"  Command="{Binding AddDelCommand}" CommandParameter="{Binding CurrentItem}"/>

на

<Button  Text="В корзину"  Command="{Binding Source={x:Reference MyListViewKategor}, Path=BindingContext.AddDelCommand}" CommandParameter="{Binding .}"/>

Мой вариант.

Код XAML:

 <StackLayout Padding="5">
    <ListView x:Name="MyListViewKategor"
              ItemsSource="{Binding Items}"
              HasUnevenRows="True">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout  Orientation="Horizontal"  BackgroundColor="White" >
                        <StackLayout WidthRequest="160" HeightRequest="120"  Padding="10">
                            <Image Source="{Binding ImageName}"   />
                        </StackLayout>
                        <StackLayout >
                            <Label  Text="{Binding Name}"  />
                            <Label Text="{Binding CountOneitem}" />
                            <Label Text="{Binding Rub}" />
                            <Button  Text="В корзину"  Command="{Binding Source={x:Reference MyListViewKategor}, Path=BindingContext.AddDelCommand}" CommandParameter="{Binding .}"/>
                        </StackLayout>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <StackLayout>
        <!-- тест стек находится под листвью -->
        <Label Text="{Binding Message}"/>
        <Button  Text="В корзину"  Command="{Binding AddDelCommand}"/>
    </StackLayout>
</StackLayout>

ViewModel:

public class KorzinaViewModel : INotifyPropertyChanged
{
    public ObservableCollection<Item> Items { get; set; }
    public ICommand AddDelCommand => new Command(OnAddDel);
    private string _message = "default text";
    public string Message
    {
        get { return _message; }
        set
        {
            _message = value;
            OnPropertyChanged(nameof(Message));
        }
    }
    public KorzinaViewModel()
    {
        Items = new ObservableCollection<Item>
        {
            new Item{ Name = "Item1", Rub=100.99 },
            new Item{ Name = "Item2", Rub=200.99 },
            new Item{ Name = "Item3", Rub=300.99 }
        };
    }
    private void OnAddDel(object obj)
    {
        if (obj is Item item)
            Message = item.Name;
        else
            Message = "click";
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Model:

public class Item
{
    public string Name { get; set; }
    public double Rub { get; set; }
}
READ ALSO
Отправка данных на сервер с опустевшей формой

Отправка данных на сервер с опустевшей формой

На странице изначально есть форма (метод POST) с кнопкой "Проверить", которая обрабатывается в этом же файле и выводит введенный текст в генерирующуюся...

228
Не получается получить запрос GET через CURL

Не получается получить запрос GET через CURL

Есть URL страница , которую я должен получить через CURL

250
Подключение файлов в PHP

Подключение файлов в PHP

Интересует следующий вопросЕсть файл с функциями main_menu

230
Перехват вызова метода

Перехват вызова метода

Есть интерфейс

303