Xamarin.Forms How to two-way bind to a control in Listview - c#

Im having a hard time trying to figure out how to set up a two-way binding for a control inside a listview.
Im using ReactiveUI and Xamarin.Forms.
In this case i would like to load a list of objects that have a quantity. This is set initially when the page loads. However i would like to be able to change these quantity values in the view when the program is run. I used an Entry for that.
Setting up a two-way Binding for the List itself (done in code behind, the reactive way) is not possible. It will error.
Is there another way to observe changes done to the Text property in the Entry control and reflect them to the according item from the list in my viewmodel?
I've been having trouble finding a solution for this and don't really know how to go about this.
Here is my XAML code:
<CustomControls:AutoLoadListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Margin="20,0,0,0" Orientation="Vertical" HorizontalOptions="StartAndExpand">
<Label Margin="0,5,0,-5" Style="{StaticResource ViewCellPrimaryLabelStyle}" x:Name="txt" Text="{Binding itemname}" />
<Label Margin="0,-5,0,5" Style="{StaticResource ViewCellSecondaryLabelStyle}" x:Name="barcode" Text="{Binding productcode}" />
</StackLayout>
<Entry Margin="5,0,5,0" x:Name="quantity" Text="{Binding quantity}">
<Entry.BindingContext>
<ViewModel:AankoopEditViewModel />
</Entry.BindingContext>
</Entry>
<Image Margin="5,5,5,5" x:Name="delete" Source="{Mobile:ImageResource tbin_pos.png}">
<Image.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Path=BindingContext.DeleteCommand,Source={x:Reference Name=AankoopEditPage}}"
CommandParameter="{Binding}" />
</Image.GestureRecognizers>
</Image>
</ViewCell>
</DataTemplate>
</CustomControls:AutoLoadListView.ItemTemplate>
My Viewmodel:
public class AankoopEditViewModel : BaseViewModel
{
private VmPurchase Purchase;
public AankoopEditViewModel()
{
PurchaseList = new ReactiveObservableCollection<AankoopEditListItem>()
{
ChangeTrackingEnabled = true
};
this.WhenAnyValue(x => x.PurchaseID).SubscribeOn(RxApp.MainThreadScheduler).Subscribe((x) =>
{
this.Purchase = DatabaseHelper.Purchase.LoadSingleById<VmPurchase>(PurchaseID);
if (Purchase != null)
{
this.Title = Purchase.supplier.name;
using (PurchaseList.SuppressChangeNotifications())
{
foreach (var detail in Purchase.purchasedetails)
{
PurchaseList.Add(new AankoopEditListItem { productcode = detail.item.code, itemname = detail.item.namenl, identifier = detail.key, quantity = detail.quantity.ToString() });
}
}
}
});
try
{
this.WhenAnyValue(x => x.PurchaseList).SubscribeOn(RxApp.MainThreadScheduler).Subscribe((x) =>
{
Console.WriteLine("The List has changed");
});
}
catch (Exception e)
{
return;
}
}
private string _purchaseID;
public string PurchaseID
{
get { return _purchaseID; }
set { this.RaiseAndSetIfChanged(ref _purchaseID, value); }
}
private ReactiveObservableCollection<AankoopEditListItem> _purchases;
public ReactiveObservableCollection<AankoopEditListItem> PurchaseList
{
get
{
return this._purchases;
}
set
{
this.RaiseAndSetIfChanged(ref _purchases, value);
}
}
My Model :
public class AankoopEditListItem : ReactiveObject
{
public string identifier { get; set; }
public string itemname { get; set; }
public string productcode { get; set; }
public string quantity { get; set; }
}

Be careful, when you do this
<Entry.BindingContext>
<ViewModel:AankoopEditViewModel />
</Entry.BindingContext>
you create a new instance of your view model for each item and you bind your Entry to it. Just remove it and keep the binding as it is (Text="{Binding quantity}") if you want to bind your entry to the row view model

Related

How to track changes of a property of a model

I have this properties on my model.
public class Student : BindableBase
{
public Guid Id { get; set; }
public string Fullname { get; set; }
private bool _isSelected;
public bool IsSelected { get => _isSelected; set => SetProperty(ref _isSelected, value); }
}
And in my ViewModel basically loads all the students and assigned it into the Collection.
public ObservableRangeCollection<Student> Students { get; } = new();
private List<Guid> SelectedIds { get; set; }
public override async Task OnActivatedAsync()
{
var results = await _service.GetAllStudents(take: 100);
Students.ReplaceRange(results);
}
And in my Xaml
<CollectionView ItemsSource="{x:Binding Students}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="vm:Student">
<StackLayout>
<StackLayout Margin="0,20" Orientation="Horizontal">
<CheckBox IsChecked="{x:Binding IsSelected}" />
<StackLayout>
<Label
FontAttributes="Bold"
FontSize="17"
Text="{x:Binding Fullname}"
TextColor="{x:StaticResource ColorBlack}"
VerticalOptions="Center" />
</StackLayout>
</StackLayout>
<BoxView HeightRequest="1" Color="Gray" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Now what I want to achieve is that whenever I select an item I want it to be added to a new List of items object right away. But for now I don't have an idea how to do such thing.
Any help is much appreciated.
Thanks in advance
I can check who among of the students that has IsSelected = true by using Linq but this is during Save button. But what I wanted to do now is during check and uncheck it is being added/remove in a new List object, which is I'm having a hard time how to implement.

Xamarin UWP seems to bind to the wrong view model

I have a Xamarin project for Android and UWP. This issue seems to only happen on UWP.
In my Xamarin project I have ContentPage with a view model bound as context. In this ViewModel there's an ObservableCollection with another kind of view model. When I create a new instance of this underlying ViewModel and add to my ObservableCollection, sometimes the ContentPage works as expected, showing an item in my ListView. But sometimes there's an empty element added, that I can see when hovering over the list. When this happens I get a bunch of warnings in the Output tab.
My DownloadsPage:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Downloader.Converters"
mc:Ignorable="d"
x:Class="Downloader.Views.DownloadsPage">
<ContentPage.Resources>
<ResourceDictionary>
<local:DownloadStatusToColorConverter x:Key="downloadStatusToColor" />
</ResourceDictionary>
</ContentPage.Resources>
<RefreshView IsRefreshing="{Binding IsBusy, Mode=TwoWay}" Command="{Binding LoadItemsCommand}">
<ListView x:Name="DownloadsListView" SelectionMode="None" ItemsSource="{Binding Downloads}" RowHeight="70">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10" BackgroundColor="{Binding DownloadStatus, Converter={StaticResource downloadStatusToColor}}">
<Label Text="{Binding Name}"
d:Text="{Binding .}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
<Grid Grid.Row="0" Grid.Column="0" Padding="10,0,10,0">
<ProgressBar BackgroundColor="Transparent" Progress="{Binding PercentDownloaded}" HorizontalOptions="FillAndExpand" HeightRequest="20">
</ProgressBar>
<Label Text="{Binding PercentString}" HorizontalTextAlignment="Center"></Label>
</Grid>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RefreshView>
</ContentPage>
DownloadsViewModel is set as context in the code-behind like this:
public partial class DownloadsPage : ContentPage
{
private readonly DownloadsViewModel _viewModel;
public DownloadsPage()
{
InitializeComponent();
BindingContext = _viewModel = new DownloadsViewModel();
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
Device.BeginInvokeOnMainThread(() => _viewModel.RefreshDownloads());
return true;
});
}
}
The bound DownloadsViewModel:
public class DownloadsViewModel : BaseViewModel
{
public ObservableCollection<DownloadViewModel> Downloads { get; set; } = new ObservableCollection<DownloadViewModel>();
public Command LoadItemsCommand { get; set; }
public DownloadsViewModel()
{
Title = "Downloads";
LoadItemsCommand = new Command(() => {
IsBusy = true;
Downloads.Clear();
RefreshDownloads();
IsBusy = false;
});
}
public void RefreshDownloads()
{
foreach (var download in DownloadManager.GetDownloads())
{
var existingDownload = Downloads.FirstOrDefault(d => d.Id == download.Id);
if (existingDownload != null)
{
existingDownload.UpdateValues(download);
}
else
{
Downloads.Add(new DownloadViewModel(download));
}
}
}
}
And the ObservableCollection contains DownloadViewModel that looks like this:
public class DownloadViewModel : BaseViewModel
{
private IDownload _download;
public DownloadViewModel(IDownload download)
{
UpdateValues(download);
}
private string _id;
public string Id
{
get { return _id; }
set { SetProperty(ref _id, value); }
}
private string _name;
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
private DownloadStatus _status;
public DownloadStatus DownloadStatus
{
get { return _status; }
set { SetProperty(ref _status, value); }
}
public double PercentDownloaded
{
get
{
return _download.DownloadedBytes == -1
? 0f
: (double)_download.DownloadedBytes / _download.TotalBytes;
}
}
public string PercentString { get => $"{(int)(PercentDownloaded * 100)} %"; }
public void UpdateValues(IDownload download)
{
_download = download;
Id = _download.Id;
Name = _download.Name;
DownloadStatus = _download.Status;
}
}
The error I sometimes get which causes items in my ListView to be empty:
Binding: 'DownloadStatus' property not found on 'Downloader.ViewModels.DownloadsViewModel', target property: 'Xamarin.Forms.StackLayout.BackgroundColor'
Binding: 'Name' property not found on 'Downloader.ViewModels.DownloadsViewModel', target property: 'Xamarin.Forms.Label.Text'
Binding: 'PercentDownloaded' property not found on 'Downloader.ViewModels.DownloadsViewModel', target property: 'Xamarin.Forms.ProgressBar.Progress'
Binding: 'PercentString' property not found on 'Downloader.ViewModels.DownloadsViewModel', target property: 'Xamarin.Forms.Label.Text'
When debugging I've confirmed that the item is added to my ObservableCollection as expcted.
How come sometimes it's looking for DownloadStatus, Name, PercentDownloaded and PercentString on DownloadsViewModel instead of DownloadViewModel?
Xamarin UWP seems to bind to the wrong view model
I checked your code sample and it works as expect. But I found the progress value does not update automatically that cause the listview item can't display, I have update the IDownload interface add PercentDownloaded property. For the testing it could works in uwp platform.
The problem was that the ViewModels did not have setters with INotifyPropertyChanged implemented for all properties. The source code is available on Github, and the commit that fixes the issue is this one.

How to fix ListView not showing contents of ObservableCollecton which is binded to it's ItemSource [duplicate]

This question already has an answer here:
Databindings don't seem to refresh
(1 answer)
Closed 3 years ago.
I am using MVVM pattern in my Xamarin.Forms application. I am trying to fill my page with a list of cards with simple information. For that I am using an ObservableCollection (CardsCollectionViewModel.cs) and objects of the class(CardViewModel) which are stored in the collection.
The Collection is initialized and passed to the MainPage.xaml.cs class. In the MainPage.xaml the collection name is binded to ListView ItemSource and the properties of storing objects are binded to the contents of list.
After the program starts and loads the Cards collections successfull, the page appears to be left empty.
Full project here: https://github.com/InfroLab/barkot/tree/master/Barkot
Here is my card class:
CardViewModel.cs
public class CardViewModel : INotifyPropertyChanged
{
//some code
public CardViewModel(int id, string company, string barcode, string type, string site)
{
//some code
}
private int id;
private string company = "";
private string barcode = "";
private string type = "";
private string site = "";
public int Id { get; set; }
public string Company
{
get { return company; }
set
{
//Console.WriteLine("{0}", Company);
if (company != value)
{
company = value;
OnPropertyChanged("Company");
}
}
}
public string Barcode
{
get { return barcode; }
set
{
if (barcode != value)
{
barcode = value;
OnPropertyChanged("Barcode");
}
}
}
public string Type
{
get { return type; }
set
{
if (type != value)
{
type = value;
OnPropertyChanged("Type");
}
}
}
public string Site
{
get { return site; }
set
{
if (site != value)
{
site = value;
OnPropertyChanged("Site");
}
}
}
}
Here is my collection class:
CarCollectionViewModel.cs
public class CardCollectionViewModel : INotifyPropertyChanged
{
public static ObservableCollection<CardViewModel> Cards { get; set; }
//some code
public static void UpdateCards()
{
//gettingitems from local db
Cards = App.Database.GetItems();
}
public CardCollectionViewModel()
{
Cards = new ObservableCollection<CardViewModel>();
UpdateCards();
//some code
}
}
Here is ListView from MainPage.xaml:
<ListView SeparatorVisibility="None" HasUnevenRows="True" ItemsSource="{Binding Cards}" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Frame Margin="10" HeightRequest="148" Padding="10" CornerRadius="5" HasShadow="True" BackgroundColor="#FFFFFF" InputTransparent="False" >
<StackLayout Orientation="Vertical">
<Button Text="Edit" Command="{Binding EditCardCommand}" BackgroundColor="#EBEBEB" HeightRequest="20" HorizontalOptions="End"/>
<StackLayout Orientation="Horizontal">
<WebView Source="{Binding Site}" HeightRequest="128" WidthRequest="128" VerticalOptions="FillAndExpand"/>
<StackLayout Spacing="5" Orientation="Vertical">
<Label Text="{Binding Company}" FontSize="Small" TextColor="#232323" />
<Label Text="{Binding Barcode}" FontSize="Small" TextColor="#232323" />
<forms:ZXingBarcodeImageView BarcodeFormat="{Binding Type}" BarcodeValue="{Binding Barcode}" HeightRequest="40" WidthRequest="200">
<zx:ZXingBarcodeImageView.BarcodeOptions>
<zxcm:EncodingOptions Width="200" Height="40" PureBarcode="True"/>
</zx:ZXingBarcodeImageView.BarcodeOptions>
</forms:ZXingBarcodeImageView>
</StackLayout>
</StackLayout>
</StackLayout>
</Frame>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I expect to see a loaded list on my page, but the actual content of it is empty.
SOLUTION:
private ObservableCollection<CardViewModel> cards = new ObservableCollection<CardViewModel>();
public ObservableCollection<CardViewModel> Cards
{
get
{
return cards;
}
set
{
if (cards != value)
{
cards = value;
OnPropertyChanged("Cards");
}
}
}
when you update Cards
Cards = App.Database.GetItems();
you are not raising a PropertyChanged event because you are using a default getter for Cards

Xamarin.forms MVVM. Listview remains empty

I'm very new to Xamarin.Forms and MVVM and posting questions here on StackOverflow so bear with me please. I'm trying to fill a listview in Xamarin.Forms. I first programmed it without MVVM and it all worked like I wanted it to, but now I wanted to get in in MVVM and that is where it went wrong, now my list won't fill up anymore.
I made a viewmodel and only put all the binding in the viewmodel, I have not yet implemented eventhandlers.
This is a part of the code behind (I have a couple more eventhandlers but that is not relevant right now):
namespace CCXamarinApp
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PatientsWithTagPage : ContentPage
{
public PatientsWithTagPage()
{
BindingContext = new PatientsWithTagViewModel();
InitializeComponent();
(BindingContext as PatientsWithTagViewModel).GetAllPatients();
if((BindingContext as PatientsWithTagViewModel).IsEmptyPatientList)
HandleEmptyList();
else
(BindingContext as PatientsWithTagViewModel).SortAndShowPatients();
}
private void SearchBar_OnTextChanged(object sender, TextChangedEventArgs e)
{
(BindingContext as PatientsWithTagViewModel).Searching(e.NewTextValue);
}
...
This is my XAML page:
<SearchBar x:Name="SearchBar" Placeholder="Zoek op naam of plaats..." HeightRequest="25" Margin="10"
TextChanged="SearchBar_OnTextChanged"/>
<Label Text="{Binding LastRefreshed}" FontAttributes="Italic" FontSize="15" />
<Label x:Name="LabelEmptyList" FontSize="17" Text="Geen gegevens gevonden" FontAttributes="Bold"
IsVisible="False" />
<ListView x:Name="PatientListView" HasUnevenRows="True" SeparatorColor="Accent"
VerticalOptions="FillAndExpand" IsPullToRefreshEnabled="True" IsRefreshing="{Binding IsFetchingData, Mode=TwoWay}"
Refreshing="PatientListView_OnRefreshing" SelectedItem="{Binding SelectedPatient, Mode=TwoWay}"
ItemSelected="PatientListView_OnItemSelected" ItemsSource="{Binding Patients}"
IsVisible="True" BackgroundColor="Aqua">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Spacing="4">
<StackLayout Orientation="Horizontal" Margin="10,7,10,1">
<Label Text="{Binding FullName}" FontAttributes="Bold" FontSize="16" />
<Label Text="{Binding DisplayTimeOfLastScan, StringFormat='{0}'}"
HorizontalOptions="EndAndExpand" />
</StackLayout>
<StackLayout Orientation="Horizontal" Margin="10,0,10,7">
<Label Text="{Binding LastLocation}" HorizontalOptions="Start" />
<Label Text="{Binding DisplayDurationSinceLastScan, StringFormat='al {0}'}"
HorizontalOptions="EndAndExpand" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
This is my viewmodel (not all the code but the code that is most relevant). The BaseViewModel it derives from is from the nuget package "Refractored.Mvvmhelpers":
class PatientsWithTagViewModel : BaseViewModel
{
public ObservableCollection<PatientViewModel> Patients { get; private set; } = new ObservableCollection<PatientViewModel>();
private PatientViewModel selectedPatient;
public PatientViewModel SelectedPatient
{
get => selectedPatient;
set => SetProperty(ref selectedPatient, value);
}
private readonly JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings
{
DateFormatString = "dd-MM-yyyTH:mm",
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
};
public bool IsEmptyPatientList => Patients.Count == 0;
private string testJson = "[{\"firstName\":\"P.\",\"lastName\":\"Selie\",\"tag\":{\"tagId\":\"124\",\"tagSerialNumber\":\"ABC135\"},\"scans\":[{\"location\":\"Tuin\",\"dateTime\":\"May01,2018,10:10\"},{\"location\":\"Eetzaal\",\"dateTime\":\"May02,2018,10:15\"},{\"location\":\"Gang\",\"dateTime\":\"May02,2018,11:10\"},{\"location\":\"Kamer23\",\"dateTime\":\"May02,2018,12:09\"}],\"id\":\"dcc4fe9929b3681f\"}," +
"{\"firstName\":\"W.\",\"lastName\":\"Janssens\",\"tag\":{\"tagId\":\"132\",\"tagSerialNumber\":\"ABC167\"},\"scans\":[{\"location\":\"Kamer23\",\"dateTime\":\"May01,2018,23:39\"},{\"location\":\"Gang\",\"dateTime\":\"May02,2018,04:10\"},{\"location\":\"Eetzaal\",\"dateTime\":\"May02,2018,04:11\"},{\"location\":\"Gang\",\"dateTime\":\"May02,2018,04:20\"},{\"location\":\"Kamer23\",\"dateTime\":\"May02,2018,04:22\"}],\"id\":\"a6dac28475327922\"}]";
public void GetAllPatients()
{
IsFetchingData = true;
try
{
Patients = new ObservableCollection<PatientViewModel>(
JsonConvert.DeserializeObject<ObservableCollection<PatientViewModel>>(testJson,
jsonSerializerSettings));
}
catch(Exception e)
{
Console.WriteLine("*****ERROR kon API niet ophalen");
Console.WriteLine(e.Message);
}
finally
{
IsFetchingData = false;
}
}
This is the model I use:
public class Patient : ObservableObject
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Tag Tag { get; set; }
public List<Scan> Scans { get; set; }
public string Id { get; set; }
public override string ToString()
{
return LastName + ", " + FirstName;
}
}
It also has its own viewmodel with properties like DisplayDurationSinceLastScan, but I don't think it is relevant here, if you think it is, let me know.
So with this code I get my page but there seems to be no items in the list, if I debug, Patients is filled with items so it is not empty at all, but something goes wrong with the binding I guess but no error is given.
Here is a picture of what I get: the listview is shown (I added a blue background so I would know if the listview was visible or not), but there are no items in there. Still Patients is filled when I debug the app.
Does someone see the mistake I made?
I see some issues with your code here from a maintainability point of view. Try to keep all your code inside the view model instead of both the view model and code behind. Ideally, your code behind contains nothing and if anything it strictly has to do with visual things.
Anyway, in regard to you problem: you are creating a new ObservableCollection each time. That breaks the binding. Just keep the new ObservableCollection at the top and then when new data comes in, clear that and repopulate it. Like this:
public void GetAllPatients()
{
IsFetchingData = true;
try
{
var resultPatients = JsonConvert.DeserializeObject<ObservableCollection<PatientViewModel>>(testJson, jsonSerializerSettings);
Patients.Clear();
foreach (var patient in resultPatients)
Patients.Add(patient);
}
catch(Exception e)
{
Console.WriteLine("*****ERROR kon API niet ophalen");
Console.WriteLine(e.Message);
}
finally
{
IsFetchingData = false;
}
}
Your data should now show up.

C# Count items Xamarin

I have model with 3 fields : TItle, Body, Status.
public class Names
{ [PrimaryKey]
public string Title { get; set; }
public string Body { get; set; }
public string Status{ get; set; }}
When user opens the page he can see list of names with fields (Title, Body).
Code of page looks like:
xaml.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HomePage : ContentPage
{
public ObservableCollection<Models.Names> items { get; set; }
public HomePage()
{
items = new ObservableCollection<Models.Names>();
this.BindingContext = this;
InitializeComponent();
List.ItemSelected += (sender, e) => {
((ListView)sender).SelectedItem = null;
};
List.Refreshing += (sender, e) => {
LoadUsersData();
};
LoadUsersData();
}
public async void LoadUsersData()
{
List.IsRefreshing = true;
var Names= await App.Database.Names.GetItemsAsync();
items.Clear();
foreach (var item in Names)
items.Add(item);
List.IsRefreshing = false;
}
}
xaml
<StackLayout>
<ListView x:Name="List"
HasUnevenRows="True"
ItemsSource="{Binding items}"
IsPullToRefreshEnabled="True">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell
Text="{Binding Title}"
Detail="{Binding Body}"
TextColor="Black"
DetailColor="Gray">
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
In the begin of page I want to add string which shows amount of all items with Status = "New".
How I can do it?
Add a Label that binds to the Count property of your ObservableCollection (it will be notified each time items are added/deleted from your collection):
<Label Text="{Binding items.Count, StringFormat='Status = {0}'}"/>
Update
If you need custom properties, like the number of Names objects with a Status of "new", there are multiple ways to create bindable properties, but one way is to subclass ObservableCollection and add your custom property:
public class MyObservableCollection : ObservableCollection<Names>
{
public MyObservableCollection()
{
CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) =>
{
OnPropertyChanged(new PropertyChangedEventArgs("NewCount"));
};
}
public int NewCount
{
get { return this.Count((Names arg) => arg.Status == "new"); }
}
}
Now replace your use of ObservableCollection with MyObservableCollection.
public MyObservableCollection items { get; set; }
In your XAML, you can now bind on NewCount:
<Label Text="{Binding items.Count, StringFormat='Status = {0}'}"/>
<Label Text="{Binding items.NewCount, StringFormat='Status = {0}'}"/>
In terms using a BindableProperty instead, there are other SO question/answers already posted and a great blog post:
https://xamarinhelp.com/bindable-properties-xamarin-forms/

Categories