Reputation: 159
I'm trying to write a shopping list app. When you change a checkbox it should reorder the list so unchecked items are at the top and checked items are at the bottom.
When I tried ordering on the CheckedChanged event it got stuck in a infinite loop because the CheckedChange event appears to fire when ordering.
I also tried having two separate lists, one to hold the old values and one to hold the current value and bind to the the listview. This gives the following error and hides some of the labels:
requestLayout() improperly called by md5f92e0daf340890c9667469657ee2ece8.LabelRenderer
I am using this code to get the error:
async void CheckChange(object sender, CheckedChangedEventArgs e)
{
CheckBox checkbox = (CheckBox)sender;
var selectedProduct = checkbox.BindingContext as Product;
if (selectedProduct == null)
{
return;
}
var oldProduct = _oldProducts.First(x => x.ProductId == selectedProduct.ProductId);
if (oldProduct.IsChecked == selectedProduct.IsChecked)
{
return;
}
listView.ItemsSource = _products.OrderBy(x => x.IsChecked);
listView.ItemsSource = new ObservableCollection<Product>(_products.OrderBy(x => x.ProductId).ToList());
await _connection.UpdateAsync(selectedProduct);
var prod = _oldProducts.First(x => x.ProductId == selectedProduct.ProductId);
prod.IsChecked = selectedProduct.IsChecked;
}
Upvotes: 1
Views: 894
Reputation: 18861
You can binding the value of the property IsChecked of your model .And handle the logic in code behind .
<CheckBox IsChecked="{Binding IsCheck , Mode=TwoWay}" />
public class Product : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public int Id { get; set; }
public string Title { get; set; }
private bool ischeck;
public bool IsCheck
{
get
{
return ischeck;
}
set
{
if (ischeck != value)
{
ischeck = value;
NotifyPropertyChanged();
}
}
}
}
foreach(var product in MyItems) // MyItems here is ItemsSource of your listview
{
product.PropertyChanged += Product_PropertyChanged;
}
//...
private void Product_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName== "IsCheck")
{
var newSources = MyItems.OrderBy(x => x.IsCheck);
listView.ItemsSource = newSources;
}
}
Upvotes: 3