Кнопка привязки к команде внутри списка данных - PullRequest
0 голосов
/ 01 июля 2018

Я наткнулся на это решение, которое должно привязываться к корневой странице, а не к списку, который у меня не работает (я пытаюсь выполнить команду, когда кнопка нажата внутри списка, и передать ей идентификатор элемента списка) прямо сейчас ( Задан путь = BindingContext.RequestAccepted) Невозможно разрешить свойство "RequestAccepted" в контексте данных объекта типа.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:viewModels="clr-namespace:XamarinApp.ViewModels;assembly=XamarinApp"
         x:Name="RequestsPage"
         x:Class="XamarinApp.ViewModels.Views.CustomerTransferRequestsPage">

<ContentPage.BindingContext>
    <viewModels:CustomerTransferRequestsViewModel/>
</ContentPage.BindingContext>

<ContentPage.Content>
    <StackLayout >
        <Label Text="لا يوجد لديك طلبات حالياً" IsVisible="{Binding EmptyLableVisible}"  ></Label>


        <ActivityIndicator IsRunning="{Binding IsLoading}" HorizontalOptions="FillAndExpand"
                           VerticalOptions="FillAndExpand"/>



        <ListView ItemsSource="{Binding RequestedItems}" 
                  HasUnevenRows="True"
                  ItemTapped="ListView_OnItemTapped"
        >

            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>

                            <Label Text="{Binding RequestUserName}"></Label>
                            <Label Text="{Binding ItemsName}"></Label>
                            <Label Text="{Binding ItemsPrice}"></Label>

                            <StackLayout Orientation="Vertical">

                                <Button Text="قبول" Command="{Binding Source={x:Reference RequestsPage}, Path=BindingContext.RequestAccepted}"></Button>
                                <Button Text="رفض"></Button>

                            </StackLayout>


                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

    </StackLayout>
</ContentPage.Content>

Модель представления

 public class CustomerTransferRequestsViewModel : INotifyPropertyChanged
{

  public CustomerTransferRequestsViewModel()
    {
        if (GetRequestedItems.CanExecute(null))
        {
            GetRequestedItems.Execute(null);
        }
    }
    ApiServices _apiServices = new ApiServices();

    private ObservableCollection<GetCustomerTransferOrderRespond> _requestedItems;
    private bool _emptyLableVisible;
    private bool _isLoading;

    public ObservableCollection<GetCustomerTransferOrderRespond> RequestedItems
    {
        get => _requestedItems;
        set
        {
            if (Equals(value, _requestedItems)) return;
            _requestedItems = value;
            OnPropertyChanged();
        }
    }

    public bool EmptyLableVisible
    {
        get => _emptyLableVisible;

        set
        {
            if (Equals(value, _emptyLableVisible)) return;
            _emptyLableVisible = value;
            OnPropertyChanged();
        }

    }

    public bool IsLoading { get => _isLoading; set 
        {
            if (Equals(value, _isLoading)) return;
            _isLoading = value;
            OnPropertyChanged();
        }
    }

    public ICommand GetRequestedItems
    {

        get
        {
            return new Command(async () =>
            {
                IsLoading = true;
                var accesstoken = Settings.AccessToken;
                RequestedItems = await _apiServices.GetCustomerTranferOrdersAsync(accesstoken);

                if (RequestedItems == null)
                {
                    EmptyLableVisible = true;
                    IsLoading = false;
                }
                else
                {
                    EmptyLableVisible = false;
                    IsLoading = false;
                }

            });
        }
    }


    public ICommand RequestAccepted
    {
        get
        {
            return new Command(async () =>
            {
                //RequestAccepted Logic

            });
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Ответы [ 3 ]

0 голосов
/ 02 июля 2018

Я использую для создания ViewModel для каждого элемента в списке. Если у меня уже есть модель, я использую ее внутри ViewModel, часто в свойстве Item. Так что в привязке я напишу Item.RequestUserName например. Но это позволяет мне добавлять команды в ViewModel и связываться с ними.

0 голосов
/ 02 июля 2018

Я думаю, что вам нужно определить свойство ICommand и назначить с помощью Command,

Примерно так же во ViewModel.

public ICommand RequestAccepted
    {
        get;
        set;
    }

в конструкторе вы можете назначить свойство с помощью команды, подобной этой,

public CustomerTransferRequestsViewModel()
    {
        if (GetRequestedItems.CanExecute(null))
        {
            GetRequestedItems.Execute(null);
        }
        RequestAccepted = new Command(() =>
        {
            //code goes here
        });

    }

.XAML Page

<?xml version="1.0" encoding="utf-8"?>
<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Name="RequestsPage"
    xmlns:local="clr-namespace:Stack51123113"
    x:Class="Stack51123113.MainPage">
    <ContentPage.BindingContext>
        <local:CustomerTransferRequestsViewModel />
    </ContentPage.BindingContext>
    <ContentPage.Content>
        <StackLayout>
            <Label
                Text="لا يوجد لديك طلبات حالياً">
            </Label>
            <ListView
                ItemsSource="{Binding RequestedItems}"
                HasUnevenRows="True">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout>
                                <Label
                                    Text="{Binding RequestUserName}">
                                </Label>
                                <Label
                                    Text="{Binding ItemsName}">
                                </Label>
                                <Label
                                    Text="{Binding ItemsPrice}">
                                </Label>
                                <StackLayout
                                    Orientation="Vertical">
                                    <Button
                                        Text="قبول"
                                        Command="{Binding Source={x:Reference RequestsPage}, Path=BindingContext.RequestAccepted}">
                                    </Button>
                                    <Button
                                        Text="رفض">
                                    </Button>
                                </StackLayout>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

ViewModel

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Xamarin.Forms;

namespace Stack51123113
{
    public class CustomerTransferRequestsViewModel : INotifyPropertyChanged
    {

        public CustomerTransferRequestsViewModel()
        {
            if (GetRequestedItems.CanExecute(null))
            {
                GetRequestedItems.Execute(null);
            }
            RequestAccepted = new Command(() =>
            {
                //code goes here
            });

        }
        ApiServices _apiServices = new ApiServices();

        private ObservableCollection<GetCustomerTransferOrderRespond> _requestedItems;
        private bool _emptyLableVisible;
        private bool _isLoading;

        public ObservableCollection<GetCustomerTransferOrderRespond> RequestedItems
        {
            get => _requestedItems;
            set
            {
                if (Equals(value, _requestedItems)) return;
                _requestedItems = value;
                OnPropertyChanged();
            }
        }

        public bool EmptyLableVisible
        {
            get => _emptyLableVisible;

            set
            {
                if (Equals(value, _emptyLableVisible)) return;
                _emptyLableVisible = value;
                OnPropertyChanged();
            }

        }

        public bool IsLoading
        {
            get => _isLoading; set
            {
                if (Equals(value, _isLoading)) return;
                _isLoading = value;
                OnPropertyChanged();
            }
        }

        public ICommand GetRequestedItems
        {

            get
            {
                return new Command(async () =>
                {
                    RequestedItems = new ObservableCollection<GetCustomerTransferOrderRespond>(new List<GetCustomerTransferOrderRespond>()
                    {
                        new GetCustomerTransferOrderRespond(),
                        new GetCustomerTransferOrderRespond(),
                    });
                });
            }
        }

        public ICommand RequestAccepted
        {
            get;
            set;
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class ApiServices
    {
        public ApiServices()
        {
        }
    }

    public class GetCustomerTransferOrderRespond
    {
    }
}
0 голосов
/ 02 июля 2018

Внутри ListView используйте «параметр команды» вместе с «clicked», чтобы получить команду для каждой кнопки отдельно.

XAML

 <Button CommandParameter="{Binding ItemID}" Clicked="ItemClicked" />

xaml.cs

 async void ItemClicked(object sender, System.EventArgs e)
 {
     var Button = (Button)sender;
     String Value = Button.CommandParameter.ToString(); // This gives the Item ID
 }

Надеюсь, это поможет.

...