我遇到了这个解决方案,该解决方案应该绑定到根页面而不是不适用于我的列表视图(我正在尝试在列表视图中按下按钮并通过它传递列表视图项ID时执行命令)已给出Path = BindingContext.RequestAccepted)。无法在类型object的数据上下文中解析属性“ 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>
viewModel
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));
}
}
答案 0 :(得分:1)
我认为您需要做的是定义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
{
}
}
答案 1 :(得分:0)
在ListView中,使用“命令参数”和“单击”来分别获取每个按钮的命令。
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
}
希望这会有所帮助。
答案 2 :(得分:0)
我用来为列表中的每个项目创建一个ViewModel。如果我已经有一个模型,则可以在ViewModel中使用它,通常在一个名为Item的属性中。因此,在绑定中,我将编写例如Item.RequestUserName。但这使我可以向ViewModel添加命令并对其进行绑定。