Reputation: 3101
My Label Binding in ListView does not read data from the AllNotes list, but it does show the length of input string. Is it because my AllNotes list is empty or is there any error in my code? I also don't find any error or exception while running the code too.
public ObservableCollection AllNotes { get; set; } = new ObservableCollection();
#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" xmlns:local="clr-
namespace:App19.ViewModel"
x:Class="App19.MainPage">
<ContentPage.BindingContext>
<local:MainPageViewModel/>
</ContentPage.BindingContext>
<Grid RowDefinitions="*,auto">
<ListView ItemsSource="{Binding AllNotes}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame>
<Label Text="{Binding .}" TextColor="Red"
FontSize="20" LineBreakMode="WordWrap" BackgroundColor="Purple"
HorizontalOptions="StartAndExpand"/>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackLayout Grid.Row="1">
<Entry Placeholder="Enter new user name: " x:Name="userEntry" Text="{Binding GetName}"/>
<Button Text="Delete" Command="{Binding Delete}"/>
<Button Text="Save" Command="{Binding Change}"/>
</StackLayout>
</Grid>
</ContentPage>
#C-Sharp
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
using System.Threading.Tasks;
using Xamarin.Essentials;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace App19.ViewModel
{
public class MainPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public MainPageViewModel()
{
Delete = new Command(() =>
{
Name = string.Empty;
GetName = string.Empty;
});
Change = new Command(() =>
{
if (GetName != string.Empty)
{
Name = GetName;
AllNotes.Add(GetName);
GetName = string.Empty;
}
});
}
public ObservableCollection<string> AllNotes { get; set; } = new
ObservableCollection<string>();
public string GetName
{
get => name;
set
{
name = value;
var args = new PropertyChangedEventArgs(nameof(GetName));
PropertyChanged?.Invoke(this, args);
}
}
public string Name
{
get => name;
set
{
name = value;
var args = new PropertyChangedEventArgs(nameof(Name));
PropertyChanged?.Invoke(this, args);
}
}
public string name;
public Command Delete { get; }
public Command Change { get; }
}
}
Upvotes: 1
Views: 472
Reputation: 897
You're setting the data in your AllNotes Observable Collection AFTER construction. This means you effectively want to update the contents of the ObservableCollection but you haven't triggered the PropertyChanged event in your set method.
Every time you wish to make a change to a field AFTER construction, you have to include;
PropertyChanged?.Invoke(this, args);
Make the following change to your code;
private ObservableCollection<string> _allNotes = new ObservableCollection<string>();
public ObservableCollection<string> AllNotes
{
get => _allNotes;
set
{
_allNotes = value;
var args = new PropertyChangedEventargs(nameof(AllNotes));
PropertyChanged?Invoke(this, args);
}
}
Depending on what your use case is, you could also opt to use CollectionView, but this is optional. it will reduce your code complexity and also included some additional Commands and features that ListView does not have.
Upvotes: 1
Reputation: 78
Try replacing the listview with the collectionview. And also replace the ViewCell with a StackLayout or a Grid when using collectionview.
You can check the documentation here below.
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/layout
Upvotes: 0