I am placing a stepper inside a Listview. I would like to know which Item the Stepper belong to when I change it. Here is the Listview. I would like to know, when I modify the stepper's value, which EAN is part of the same ViewCell.
<ListView x:Name="ItemsListView"
ItemsSource="{Binding Items}"
VerticalOptions="FillAndExpand"
HasUnevenRows="true"
RefreshCommand="{Binding LoadItemsCommand}"
IsPullToRefreshEnabled="true"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
CachingStrategy="RecycleElement"
ItemTapped="OnItemSelected"
>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10" Orientation="Vertical" HorizontalOptions="FillAndExpand">
<Label Text="{Binding Name}" LineBreakMode="WordWrap" FontSize="16" HorizontalOptions="FillAndExpand" />
<Label Text="{Binding QuantityExpectedDisplay}" LineBreakMode="WordWrap" FontSize="10" HorizontalOptions="FillAndExpand" />
<Label Text="{Binding EAN}" LineBreakMode="WordWrap" FontSize="10" HorizontalOptions="FillAndExpand" />
<Stepper Value="{Binding QuantityDefect}" Minimum="0" Maximum="{Binding Quantity}" HorizontalOptions="FillAndExpand" ValueChanged="Stepper_ValueChanged" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So that I can use that ean later to find the corresponding line. (In the example, I would like to find the ListItem, or at least its EAN in test, rather than putting a new one)
private void Stepper_ValueChanged(object sender, ValueChangedEventArgs e)
{
ListItem test = new ListItem();//Here I'd like the ViewCell Values
var line = viewModel.lines.Find(l => l.Ean == test.EAN);
line.QuantityOpen = (int)e.NewValue;
}
Thank you and have a nice day
CodePudding user response:
We generally don't recommend using this method,you can implement INotifyPropertyChanged
for your the item of Items
.
Suppose the item model is Item.cs
, you can implement INotifyPropertyChanged
as follows:
public class Item: INotifyPropertyChanged
{
public string Name { get; set; }
public string QuantityExpectedDisplay{ get; set; }
public string EAN{ get; set; }
//public int QuantityDefect { get; set; }
int _quantityDefect;
public int QuantityDefect
{
set { SetProperty(ref _quantityDefect, value); }
get { return _quantityDefect; }
}
public int Quantity { get; set; }
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
And in YourPage.xaml
,we can do like this:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10" Orientation="Vertical" HorizontalOptions="FillAndExpand">
<Label Text="{Binding Name}" LineBreakMode="WordWrap" FontSize="16" HorizontalOptions="FillAndExpand" />
<Label Text="{Binding QuantityExpectedDisplay}" LineBreakMode="WordWrap" FontSize="10" HorizontalOptions="FillAndExpand" />
<Label Text="{Binding EAN}" LineBreakMode="WordWrap" FontSize="10" HorizontalOptions="FillAndExpand" />
<Stepper Value="{Binding QuantityDefect}" Minimum="0" Maximum="10" Increment="1" HorizontalOptions="FillAndExpand" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
Note:
Once we change the stepper's value, the value of QuantityDefect
will change accordingly.
CodePudding user response:
First, see Jessie's answer for the basics of Data Binding to a list of items.
Or see example described in ListView Data Sources.
In addition, we need a way to tell viewmodel what item has changed.
MessagingCenter can do this.
MyViewModel.cs:
public MyViewModel()
{
MessagingCenter.Subscribe<MyItem>(this, "changed", Item_Changed);
}
public ObservableCollection<MyItem> Items { get; set; }
private void Item_Changed(MyItem item)
{
var index = Items.IndexOf(item);
// Make sure it is mine.
if (index >= 0)
{
// ...
}
}
MyItem.cs:
int _quantityDefect;
public int QuantityDefect
{
get => _quantityDefect;
set
{
SetProperty(ref _quantityDefect, value);
Xamarin.Forms.MessagingCenter.Send<MyItem>(this, "changed");
}
}