将按钮绑定到列表视图数据模板中的命令

Binding button to command inside listview dataTemplate

我遇到了这个解决方案,它应该绑定到根页面而不是 listview,它对我不起作用(我正在尝试在 listview 中按下按钮时执行命令并传递 listview 项目 ID)现在(Path=BindingContext.RequestAccepted) Cannot resolve 属性 "RequestAccepted" in data context of type object .

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

在 ListView 中,使用 'command parameter' 和 '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
 }

希望对您有所帮助。

我曾经为列表中的每个项目创建一个 ViewModel。如果我已经有一个模型,我会在 ViewModel 中使用它,通常在一个名为 Item 的 属性 中。所以在绑定中我会写 Item.RequestUserName 例如。但这使我可以向 ViewModel 添加命令并绑定它们。

我认为您需要做的是定义 ICommand 属性 并使用 Command 赋值,

ViewModel 中的类似内容。

public ICommand RequestAccepted
    {
        get;
        set;
    }

在构造函数中,您可以使用这样的命令分配 属性,

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

    }

.XAML 页

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