Hello,
Welcome to our Microsoft Q&A platform!
You can try to achieve it MVVM, then whatever you changed in the entry, your content in entry will be add to the model automatically. I add some content in the Entry, Then click the button to execute the command in the ViewModel. We can get all the content in all entries like following screenshot. When I add model, I did not add any names to the ObservableCollection
So, you can create new page to use my code to make a test. I do not completely use your layout, I write a layout by your design image.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ListviewControlDemo.MainPage">
<ContentPage.Content>
<StackLayout>
<StackLayout>
<ListView x:Name="listViewItensHistorico" HasUnevenRows="True" ItemsSource="{Binding Items}" ItemSelected="listViewItensHistorico_ItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<FlexLayout Margin="15" Direction="Row" Wrap="{OnIdiom Tablet=NoWrap, Phone=Wrap}">
<StackLayout Spacing="{OnIdiom Tablet=50, Phone=10}" Orientation="{OnIdiom Tablet=Horizontal, Phone=Vertical}">
<StackLayout Orientation="{OnIdiom Tablet=Vertical, Phone=Horizontal}" Spacing="{OnIdiom Tablet=10, Phone=10}" Margin="10,0">
<Label Text="{Binding ID}"/>
<StackLayout Orientation="Horizontal">
<Label Text="Produto:" FontAttributes="Bold"></Label>
<Entry Text="{Binding Name}" WidthRequest="90"></Entry>
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Description:" FontAttributes="Bold"></Label>
<Picker SelectedItem="{Binding Description}" WidthRequest="90">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Baboon</x:String>
<x:String>Capuchin Monkey</x:String>
<x:String>Blue Monkey</x:String>
<x:String>Squirrel Monkey</x:String>
<x:String>Golden Lion Tamarin</x:String>
<x:String>Howler Monkey</x:String>
<x:String>Japanese Macaque</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
</StackLayout>
</StackLayout>
<!--<StackLayout IsVisible="{Binding MostraUN2}" Orientation="{OnIdiom Tablet=Vertical, Phone=Horizontal}" Spacing="{OnIdiom Tablet=10, Phone=10}" Margin="10,0">
<Label Text="Quantidade" FontAttributes="Bold"></Label>
</StackLayout>
<StackLayout IsVisible="{Binding MostraUN2}" Orientation="{OnIdiom Tablet=Vertical, Phone=Horizontal}" Spacing="{OnIdiom Tablet=10, Phone=10}" Margin="10,0">
</StackLayout>-->
</StackLayout>
</FlexLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
<StackLayout FlexLayout.Basis="100%">
<Button Margin="{OnIdiom Tablet='0, 50'}" x:Name="btnAdicionarItens" Command="{Binding MyCommand}" Text="Adicionar"/>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Here is layout's background code.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext = new MyViewModel();
}
private void listViewItensHistorico_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
}
private void btnAdicionarItens_Clicked(object sender, EventArgs e)
{
}
}
Here is my MyViewModel.cs
, I use ObservableCollection
to contains items, then add empty MyModel
.
public class MyViewModel
{
public ObservableCollection<MyModel> Items { get; set; }
public ICommand MyCommand { protected set; get; }
public MyViewModel()
{
Items = new ObservableCollection<MyModel>();
Items.Add(new MyModel() { ID = 1 }) ;
Items.Add(new MyModel() { ID = 2 });
Items.Add(new MyModel() { ID = 3 });
Items.Add(new MyModel() { ID = 4 });
Items.Add(new MyModel() { ID = 5 });
Items.Add(new MyModel() { ID = 6 });
string str="";
MyCommand = new Command(() =>
{
foreach (MyModel item in Items)
{
str += item.Name;
}
Console.WriteLine(str);
} );
}
}
Here is MyModel.cs
, I acheve the INotifyPropertyChanged
interface, if the value of properties be changed, it will update ASAP in the ObservableCollection
.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
namespace ListviewControlDemo
{
public class MyModel: INotifyPropertyChanged
{
public string MyProperty { get; set; }
public int ID { get; set; }
string name;
public string Name
{
set
{
if (name != value)
{
name = value;
OnPropertyChanged("Name");
}
}
get
{
return name;
}
}
// public string Image { get; set; }
string description;
public string Description
{
set
{
if (description != value)
{
description = value;
OnPropertyChanged("Description");
}
}
get
{
return description;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
=======================
Update========================
After I type down the values and click the button, I need to make a multiplication depending on the chosen picker index. If I choose index 0, I'll multiply it by 2. If I chose the second index I'll multiply it by 5.
Now this is where I am stuck again because I don't quite understand how to check which index of my picker is selected to procceed with said multiplication :(
I did this already but with only one item at a time in a single view. I don't know how to do the same now for each item using Binding :(
You can get the all the item in the Command, for MVVM, we can control the model directly(get the picker selectitem index by model). You just need to change two places.
Firstly, change the Picker binding value in XAML from SelectedItem
to SelectedIndex
.
<StackLayout Orientation="Horizontal">
<Label Text="Description:" FontAttributes="Bold"></Label>
<Picker SelectedIndex="{Binding Description}" WidthRequest="90">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Baboon</x:String>
<x:String>Capuchin Monkey</x:String>
<x:String>Blue Monkey</x:String>
<x:String>Squirrel Monkey</x:String>
<x:String>Golden Lion Tamarin</x:String>
<x:String>Howler Monkey</x:String>
<x:String>Japanese Macaque</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
</StackLayout>
</StackLayout>
Then open your command in the viewModel. Get the selectIndex by Model directly, then handle it by index.
MyCommand = new Command(() =>
{
foreach (MyModel item in Items)
{
//str += item.Name;
var nameValue=int.Parse(item.Name);
if (item.Description==0)
{
item.Name = (nameValue * 2).ToString();
}
else if (item.Description == 1)
{
item.Name = (nameValue * 5).ToString();
}
}
//Console.WriteLine(str);
} );
Here is running screenshot when click Button.
Before click the button. After click the Button
Best Regards,
Leon Lu
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.