BindingContext кнопок в отдельном шаблоне ListView xamarin - PullRequest
0 голосов
/ 24 августа 2018

Итак, я разрабатываю приложения на xamarin Я пытаюсь включить отдельный DataTemplate. Мой listView ссылается на другой ContentView с шаблоном для просмотра списка, но кнопка не вызывает Icommand в модели View.

извините, мой английский не очень хорошо, но мне нужна помощь ТКС.

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

1 Ответ

0 голосов
/ 27 августа 2018

Каждый из двух ваших представлений имеет свой собственный BindingContext.Представление, которое содержит ListView, имеет BindingContext типа BasketEquipamentPartViewModel, поэтому {Binding ItensOrder} выбирает правильную коллекцию для ItemsSource.

Тогда Xamarin будет использовать BasketEquipamentPartCell несколько раз, по одному для каждого элементаколлекция, устанавливающая BindingContext для каждого OrderItem.Таким образом, BasketEquipamentPartCell не может напрямую ссылаться на BindingContext коллекции.При оценке Command="{Binding BindingContext.removeItemOder}" на кнопке Xamarin.Forms просматривает свойства OrderItem для removeItemOder, но не находит его.Когда Xamarin.Forms не может найти свойство, оно молча игнорирует его, поэтому остальная часть вашего приложения работает.

Чтобы исправить это, вам нужно определить свойство Command для OrderItem, к которому можно привязать.

Эскиз реализации

Один из подходов к этому - добавить метод в 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 избыточен) успешно найдет команду для вызова.

...