Dynamically Add Entry in a StackLayout and Retrieve Values in a List

Mohanasundharam Murugan 20 Reputation points
2023-01-25T06:26:49.88+00:00

User's image

As per the attachment, when clicked the '+' button, a new entry will display and need to store entered value in a List<string> . If 'x' clicked, the entry need to removed from the layout and removed from List<string> too.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,273 questions
{count} votes

2 answers

Sort by: Most helpful
  1. James Hamil 21,151 Reputation points Microsoft Employee
    2023-01-27T22:43:56.64+00:00

    Hi @Mohanasundharam Murugan , I recommend installing the DynamicForms package for this. This thread details how you can make dynamic entries with C#. Please let me know if you have any questions or need help implementing this.

    If this answer helped you please mark it as "Verified" so other users can reference it.

    Thank you,

    James

    0 comments No comments

  2. Wenyan Zhang (Shanghai Wicresoft Co,.Ltd.) 25,341 Reputation points Microsoft Vendor
    2023-01-30T07:56:04.0866667+00:00

    Hello,

    If you determine the upper limit of the number of arrays people and organizations, then you can create multiple entries on the page and hide them. When the + button is clicked, the entry is displayed. If you are not sure about the maximum limit number of arrays people and organizations, it is recommended that you use Collectionview, and there should be two groups in the collectionview. Besides, you could set the header(title) and footer (add button), refer to the following code:
    XAML, refer to the collectionview sample source code ,the UI is sample, you can design the layout according to your needs:

     <ContentPage.BindingContext>
            <local:CustomViewModel></local:CustomViewModel>
        </ContentPage.BindingContext>
    
        <StackLayout>
            <Button Text="save" Command="{Binding SaveCommand }"></Button>// add this saving button for testing
            <CollectionView  ItemsSource="{Binding Grouped}"
                            IsGrouped = "True"
                  >
                <CollectionView.GroupHeaderTemplate >
                    <DataTemplate>
                        <StackLayout Orientation="Horizontal"
                >
                            <Label BackgroundColor="Red" Text="{Binding Name}"/>
                        </StackLayout>
                    </DataTemplate>
                </CollectionView.GroupHeaderTemplate>
    
                <CollectionView.GroupFooterTemplate >
                    <DataTemplate>
                        <StackLayout Orientation="Horizontal"
                Padding="10,5,5,10"
                >
                            <Button Text="+" Command="{Binding AddCommand }"/>// add button
                        </StackLayout>
                    </DataTemplate>
                </CollectionView.GroupFooterTemplate>
    
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="200" ></ColumnDefinition>
                                <ColumnDefinition Width="40" ></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <Entry Grid.Column="0" Text="{Binding Name}" ></Entry>
                            <Button Grid.Column="1" Text="X" Command="{Binding RemoveCommand}" ></Button>// remove button
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </StackLayout>
    

    BindingContext and the faker data

     public class CustomViewModel
        {
            public ICommand SaveCommand { set; get; }// save button
            public ObservableCollection<GroupedModel> Grouped { get; set; }// item source
    
            public CustomViewModel()
            {
                Grouped = new ObservableCollection<GroupedModel>();
               var Organizations = new ObservableCollection<GroupItemModel>();
               var People = new ObservableCollection<GroupItemModel>();// two groups
                Organizations.Add(new GroupItemModel("jqery", (item) =>
                {
                    Grouped[0].Remove(item);// reomve action for each item
                }));
                Organizations.Add(new GroupItemModel("scripe", (item) =>
                {
                    Grouped[0].Remove(item);
                }));
                People.Add(new GroupItemModel("first people", (item) =>
                {
                    Grouped[1].Remove(item);
                }));
    
                Grouped.Add(new GroupedModel("Organizations", Organizations, (GroupItemModel)=>{// add a new item named Organizations
                    Grouped[0].Add(new GroupItemModel("Organization1", (item) =>
                    {
                        Grouped[0].Remove(item);// remove the item from source
                    }));
    
                }) );
                Grouped.Add(new GroupedModel("People", People, (GroupItemModel) => {// add action in the footer
                    Grouped[1].Add(new GroupItemModel("People1", (item) =>
                    {
                        Grouped[1].Remove(item);
                    }));
                }));
    
                SaveCommand = new Command(() =>
                {
                    foreach (GroupedModel item in Grouped)
                    {
                        foreach (var EachPeopeleAndOrganization in item)
                        {
                            Debug.WriteLine("{0}", EachPeopeleAndOrganization.Name);// display the stored value
                        }
                    }
                });
     
            }
        }
    

    Model, refer to the source code (I add the remove and add action)

    public class GroupItemModel : INotifyPropertyChanged
        {
            string name;// entry text
            public event PropertyChangedEventHandler PropertyChanged;
            public ICommand RemoveCommand { set; get; }
    
        Action<GroupItemModel> RemoveSelfAction { set; get; }
        public GroupItemModel(string name, Action<GroupItemModel> removeAction)
            {
                Name = name;
                RemoveSelfAction = removeAction;
                RemoveCommand = new Command(() =>
                {
                    RemoveSelfAction(this);
                });
            }
    
            public GroupItemModel()
            {
                RemoveCommand = new Command(() =>
                {
                    RemoveSelfAction(this);
                });
            }
    
            public string Name
            {
                set
                {
                    if (name != value)
                    {
                        name = value;
                        OnPropertyChanged("Name");
                    }
                }
                get
                {
                    return name;
                }
            }
            protected virtual void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        public class GroupedModel : ObservableCollection<GroupItemModel>
        {
            public ICommand AddCommand { set; get; }
            public string Name { get;  set; }// GroupTitle, Organization or People
           
            public GroupedModel(string name, ObservableCollection<GroupItemModel> items, Action<GroupItemModel> AddNewOneAction) : base(items)
            {
                Name = name;
                AddCommand = new Command(() =>
                {
                    AddNewOneAction(new GroupItemModel());        
                });
            }
            public override string ToString()
            {
                return Name;
            }
        }
    

    Best Regards,

    Wenyan Zhang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    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.