Home > Net >  Xamarin: Commands of BindableLayout list inside list
Xamarin: Commands of BindableLayout list inside list

Time:12-20

Hello folks!

I'm working on Xamarin Forms app and trying to achieve functionality of binded list inside of Listview. Earlier, I've had the class containing 'normal' types such as strings, longs, ints etc.

Now I was asked to add also list (so it's list inside list) and add functionality to it (specifically there are checkboxes that should fetch information if given record of list is checked, of course talking about nested items inside main list).

With BindableLayout, I was able to actually make it 'read-only', meaning that I can now see the list inside every list item. The problem is that I cannot bind Commands to that inner list (I suppose that's because of different path now).

Bear in mind that I already use grouping to group these items. So the structure is something like:

Grouped by the property from class -> ListView of Items -> inside each Item record I have this nested List.

I don't know (if that's possible of course) how to set path for these inner items. Maybe there is some other way in order to make it work. It's crucial for me to also pass parameter from that nested item with checkbox.

My XAML looks like something similiar to this:

<ListView ItemsSource="{Binding Items}">
<...>
<ListView.ItemTemplate>
 <DataTemplate>
  <ViewCell>
   <ViewCell.View>
    <Label Text="{Binding ItemText}">
     <StackLayout BindableLayout.ItemsSource="{Binding Positions}"> 
      <BindableLayout.ItemTemplate>
       <DataTemplate>
        <Label Text="{Binding PositionId}">
        <CheckBox />
       </DataTemplate>
      </BindableLayout.ItemTemplate>
     </StackLayout>
    <ViewCell.View>
   <ViewCell>
  </DataTemplate>
 </ListView.ItemTemplate>
</ListView>

Items model:

public class Items
{
 public string ItemText {get; set;}
 public List<Positions> Positions {get; set;}
}

Positions model:

public class Positions
{
 public long? PositionId {get; set;}
}

Creating this page is done by fetching from previouis page like this:

public override Page GivePage ()
    {
        ContentPage view = new ItemsView();
        var controller = new ItemsViewModel();
        view.BindingContext = controller;
        return view;
    }

In ViewModel I have my methods for fetching data from API, Commands etc. The only thing that I miss is basically handling Command for this nested item (what's also important is that I need to fetch PositionId and ItemText and the same time). Any help or suggestion is much appreciated, I'm struggling with this for a quite while now.

Edit:

With wonderful help given by both Gerald and CodingLumis I was finally able to understand what I was doing wrong, how should I bind it etc. Thank You very much!

CodePudding user response:

After getting help from Gerald Versluis and CodingLumis, I was able to resolve my problem and pass parameter. I've named my ListView, for example "myList", and then referenced it with checkbox.

I've just made it like that (following from Gerald's video):

xmlns:behaviorsPack="clr-namespace:Xamarin.Forms.BehaviorsPack;assembly=Xamarin.Forms.BehaviorsPack"

<CheckBox>
 <CheckBox.Behaviors>
  <behaviorsPack:EventToCommandBehavior EventName="CheckedChanged"
   Command="{Binding Path=BindingContext.CheckedChangedCommand,
   Source={Reference myList}}"
   CommandParameter="{Binding .}"/>
 </CheckBox.Behaviors>
</Checkbox>

Behaviors pack is just for handling CheckedChanged event into command.

In my ViewModel, It looks like:

//In class, added command
public ICommand CheckedChangedCommand { get; set; }    

//Then in ctor
CheckedChangedCommand = new Command<Position>(CheckedChanged);

//and finally, method called by command
private async void CheckedChanged(object obj)
{
 var position = obj as Position;
}

Thank You very much for Your help guys!

  • Related