因此,我正在xamarin上开发应用程序 我尝试包括单独的DataTemplate。 我的listView引用了另一个ContentView,其中有一个TempleView用于listview,但是该按钮在View模型中未调用Icommand。
对不起,我的英语不太好,但是我需要帮助 tks。
<ListView
ItemsSource="{Binding ItensOrder}"
x:Name="PartListView"
HasUnevenRows ="True"
RowHeight="110"
IsPullToRefreshEnabled= "{Binding IsNotBusy}"
CachingStrategy="RecycleElement"
IsVisible="{Binding IsNotBusy}"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1">
<ListView.SeparatorColor>
<OnPlatform x:TypeArguments="Color" iOS="{StaticResource ListSeparator}" Android="Transparent"/>
</ListView.SeparatorColor>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell StyleId="disclosure">
<local:BasketEquipamentPartCell/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
模板(BasketEquipamentPartCell)代码:
<AbsoluteLayout HorizontalOptions="StartAndExpand">
<Grid Padding="16" ColumnSpacing="16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width=".1*"/>
<ColumnDefinition Width=".1*"/>
<ColumnDefinition Width=".1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label VerticalOptions="Center" Grid.Column="0" Grid.Row="0" HorizontalOptions="StartAndExpand" Text="Código Modelo:"/>
<Label VerticalOptions="Center" Grid.Column="0" Grid.Row="1" HorizontalOptions="StartAndExpand" Text="Cópias Por Ciclo:"/>
<Label VerticalOptions="Center" Grid.Column="0" Grid.Row="2" HorizontalOptions="StartAndExpand" Text="Descrição Produto:"/>
<Label VerticalOptions="Center" Grid.Column="0" Grid.Row="3" HorizontalOptions="StartAndExpand" Text="Amount:"/>
<Label VerticalOptions="Center" Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="3" Text="{Binding EquipamentPart.EquipmentModel}"/>
<Label VerticalOptions="Center" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" Text="{Binding EquipamentPart.LifeCycle}"/>
<Label VerticalOptions="Center" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3" Text="{Binding EquipamentPart.Description}"/>
<Button Text="+" Grid.Column="1" Grid.Row="3"
BackgroundColor="DodgerBlue"
TextColor="White"
WidthRequest="100"
/>
<Label VerticalOptions="Center" Grid.Column="2" Grid.Row="3" Text="{Binding Amount}" HorizontalOptions="CenterAndExpand"/>
<Button Text="-" Grid.Column="3" Grid.Row="3"
BackgroundColor="DarkGreen"
Command="{Binding BindingContext.removeItemOder}"
TextColor="White"
WidthRequest="100"
/>
<Button Text="Delete" Grid.ColumnSpan="4" Grid.Column="0" Grid.Row="4"
BackgroundColor="DarkRed"
TextColor="White"
WidthRequest="100"
Command="{Binding Source={x:Reference BasketEquipamentPartCellPage}, Path=BindingContext.removeItemOder}"
CommandParameter="{Binding .}"/>
</Grid>
</AbsoluteLayout>`
我在viewmodel中的命令
public class BasketEquipamentPartViewModel : ViewModelBase
{
public ObservableCollection<OrderItem> ItensOrder { get; set; }
INavigation navigation;
private ICommand _removeItemOder, _addItemOder, _deleteOrder;
private uint _badgeCount;
public uint BadgeCount
{
get { return _badgeCount; }
set
{
_badgeCount = value;
OnPropertyChanged("BadgeCount");
}
}
public ICommand removeItemOder =>
_removeItemOder ?? (_removeItemOder = new Command<OrderItem>(async (item) => await removeItemOderCommandAsync(item)));
public ICommand deleteOrder =>
_deleteOrder ?? (_deleteOrder = new Command<OrderItem>(async (item) => await deleteOrderCommandAsync(item)));
public ICommand addItemOder =>
_addItemOder ?? (_addItemOder = new Command<OrderItem>(async (item) => await addItemOderCommandAsync(item)));
public BasketEquipamentPartViewModel(INavigation navigation )
{
ItensOrder = new ObservableCollection<OrderItem>();
this.navigation = navigation;
CreateMessaging();
}
public void CreateMessaging()
{
MessagingCenter.Unsubscribe<EquipamentPartOrderViewModel, EquipamentPart>(this, MessageKeys.AddProduct);
MessagingCenter.Subscribe<EquipamentPartOrderViewModel, EquipamentPart>(this, MessageKeys.AddProduct, async (sender, arg) =>
{
BadgeCount++;
await AddEquipamentPartAsync(arg);
});
}
private async Task AddEquipamentPartAsync(EquipamentPart item)
{
if (ItensOrder.Where(x => x.EquipamentPart.Equals(item)).Count() > 0)
{
var index= ItensOrder.IndexOf(ItensOrder.Where(c => c.EquipamentPart == item).FirstOrDefault());
var i = new OrderItem(ItensOrder[index].EquipamentPart, ItensOrder[index].Amount+1);
ItensOrder.RemoveAt(index);
ItensOrder.Insert(index,i);
}
else
ItensOrder.Add(new OrderItem(item, 1));
OnPropertyChanged("ItensOrder");
}
private async Task addItemOderCommandAsync(OrderItem item)
{
if (ItensOrder.Where(x => x.EquipamentPart.Equals(item.EquipamentPart)).Count() > 0)
{
var index = ItensOrder.IndexOf(ItensOrder.Where(c => c.EquipamentPart == item.EquipamentPart).FirstOrDefault());
var i = new OrderItem(ItensOrder[index].EquipamentPart, ItensOrder[index].Amount + 1);
ItensOrder.RemoveAt(index);
ItensOrder.Insert(index, i);
BadgeCount++;
}
}
private async Task removeItemOderCommandAsync(OrderItem item)
{
if (ItensOrder.Where(x => x.EquipamentPart.Equals(item.EquipamentPart)).Count() > 0)
{
var index = ItensOrder.IndexOf(ItensOrder.Where(c => c.EquipamentPart == item.EquipamentPart).FirstOrDefault());
if (ItensOrder[index].Amount > 1)
{
var i = new OrderItem(ItensOrder[index].EquipamentPart, ItensOrder[index].Amount - 1);
ItensOrder.RemoveAt(index);
ItensOrder.Insert(index, i);
BadgeCount--;
}
}
}
private async Task deleteOrderCommandAsync(OrderItem item)
{
if (ItensOrder.Where(x => x.EquipamentPart.Equals(item.EquipamentPart)).Count() > 0)
{
var index = ItensOrder.IndexOf(ItensOrder.Where(c => c.EquipamentPart == item.EquipamentPart).FirstOrDefault());
ItensOrder.RemoveAt(index);
BadgeCount-=item.Amount;
}
}
}
答案 0 :(得分:0)
两个视图中的每个视图都有其自己的BindingContext。包含ListView的视图具有类型为BasketEquipamentPartViewModel
的BindingContext,这就是{Binding ItensOrder}
为ItemsSource选择正确的集合的原因。
然后Xamarin将多次使用BasketEquipamentPartCell,对于集合的每个元素一次,将BindingContext设置为每个OrderItem。因此,BasketEquipamentPartCell没有任何直接引用集合的BindingContext的方法。在按钮上评估Command="{Binding BindingContext.removeItemOder}"
时,Xamarin.Forms将通过OrderItem的属性查找removeItemOder,但找不到它。当Xamarin.Forms找不到属性时,它会默默地忽略它,因此您的应用程序的其余部分都可以正常工作。
要解决此问题,您需要在OrderItem上定义一个可以绑定的Command属性。
实施方法草图
一种解决方法是在BasketEquipamentPartViewModel上添加一个方法,该方法使用MessagingCenter(用于其他用途)来侦听删除项的请求:
public void CreateMessaging()
{
MessagingCenter.Subscribe<OrderItem>(this, "RemoveOrderItem", RemoveItem);
// the rest of CreateMessaging you already have
}
private void RemoveItem(OrderItem itemToRemove)
{
// do the stuff you're already doing in removeItemOder
}
请注意,您似乎没有在removeItemOder中进行任何异步工作,因此您应该删除异步并使其返回void。
然后在OrderItem类中,创建如下命令:
private ICommand _removeItemOrder;
public ICommand removeItemOder => _removeItemOrder ??
(_removeItemOrder = new Command<OrderItem>(item => MessagingCenter.Send(this, "RemoveOrderItem"));
然后,{Binding BindingContext.removeItemOder}(或在这里只是{Binding removeItemOder}-BindingContext是多余的)将成功找到要调用的命令。