EliasMP EliasMP - 2 months ago 9
C# Question

Coding a ListView with Grid intoit and binded with a List of object?

Trying to render a ListView with a grid into it. The grid contains two columns. The first one, with a button. The second one, with a Label.

Model contains two attributes. First one, a List of specific object. Second one, a string.

Finally, the label of the grid inside of listview will be binded to the one random attribute of list of object of the Model.

My best approach is:

<ListView x:Name="intervectionList"
ItemsSource="{Binding .}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5">
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="1"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
</Grid.ColumnDefinitions>

<Button Text="Play" Grid.Row="0" Grid.Column="0" Clicked="OnLogginClicked"/>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding random_attribute}"/>
<BoxView Color="Navy" HeightRequest="1" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"/>

</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>


CODE-BEHIND:

public Intervection()
{
InitializeComponent();
var obj= new Model();
this.BindingContext = prueba.List_of_object;
}

public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

public void RaiseOnPropertyChange([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

public ViewModel()
{
_viewmodel = new ViewModel();
}

private ViewModel _viewmodel;

private string _attribute1;

public string Attribute1
{
get { return _attribute1; }
set { _attribute1= value; RaiseOnPropertyChange(); }
}
.............
}

public class Model
{
public List<obj> Intervencion;
public string attribute2;
// Helpers...
}


That is not rendering anything.

I tried successive approaches. Coming from Basic ListView with string, ListView of object,... and so on. The problem is coming from when I insert the grid.

After check Stackoverflow. I found this link Create Grid from Code-Behind, but this is not serving to my purpose because I canĀ“t re-write the view model. (I, even, tried to coded it).

As usual, thanks mates.

Answer

I have added the VerticalOptions to the Listview and Grid. I have created a viewmodel in which I have one property, the list of items. The viewmodel also implements INotifyPropertyChanged.

You can read about INotifyPropertyChanged here.

The INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed.

XAML :

<ListView ItemsSource="{Binding MyObservableCollection}" VerticalOptions="FillAndExpand">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
          <Grid Padding="5" VerticalOptions="Fill">
            <Grid.RowDefinitions>
              <RowDefinition Height="20"></RowDefinition>
              <RowDefinition Height="1"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="1*"></ColumnDefinition>
              <ColumnDefinition Width="3*"></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <Button Text="Play" Grid.Row="0" Grid.Column="0"/>
            <Label Grid.Row="0" Grid.Column="1" Text="{Binding .}"/>
            <BoxView Color="Navy" HeightRequest="1" Grid.Row="1" 
                     Grid.Column="0" Grid.ColumnSpan="2"/>

          </Grid>
        </ViewCell>
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>

ViewModel :

public class ListViewWithGridViewModel : INotifyPropertyChanged
{
    private ObservableCollection<string> _myObservableCollection;

    public ListViewWithGridViewModel()
    {
        MyObservableCollection = new ObservableCollection<string>(new List<string> { "abc", "xyz", "pqr", "aaa", "abc", "xyz", "pqr", "aaa", "abc", "xyz", "pqr", "aaa" });
    }

    public ObservableCollection<string> MyObservableCollection
    {
        get { return _myObservableCollection; }
        set
        {
            _myObservableCollection = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

XAML.cs :

public partial class ListViewWithGrid : ContentPage
{
    public ListViewWithGrid()
    {
        InitializeComponent();
        BindingContext = new ListViewWithGridViewModel();
    }
}
Comments