Jon doe
Jon doe

Reputation: 55

Xamarin Forms EntryCell added to an existing TableView in c# cannot be accssed in CustomViewModel

I'm new to Xamarin Forms. I've added an EntryCell to an existing TableSection of a TableView in c#. I'm trying to access the EntryCell entered value in CustomViewModel, but i'm not able to access it from my customviewmodel.

TabbedPage1

        <TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:behaviors="clr-namespace:FamTreeApp.Behaviors" xmlns:local="clr-namespace:FamTreeApp.Views"
                x:Class="FamTreeApp.Views.TabbedPage1">
        <TabbedPage.Behaviors>
            <behaviors:TabbedPageNavigationBehavior />
        </TabbedPage.Behaviors>
        <TabbedPage.Children>
            <local:Tab1 Title ="Tab1" class="material-icons" Icon ="user.png" />
            <local:Tab2 Title="Tab2" class="material-icons" Icon ="sharp_group_add_black_18.png" />

        </TabbedPage.Children>
    </TabbedPage>

Tab1.xaml

        <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="FamTreeApp.Views.Tab1">
        <TableView x:Name="SpouseTable" Intent="Form">
            <TableRoot>
                <TableSection x:Name="SpouseTS" Title="Parents">
                    <ViewCell>
                        <StackLayout x:Name="SpouseStack">

                            <Button Text="Submit" Clicked="OnSubmit"></Button>
                        </StackLayout>
                    </ViewCell>
                </TableSection>
            </TableRoot>
        </TableView>

    </ContentPage>

Tab1.xaml.cs

        using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    using Xamarin.Forms;
    using Xamarin.Forms.Xaml;

    namespace FamTreeApp.Views
    {
        [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class Tab1 : ContentPage
        {

            public Tab1()
            {
      
                InitializeComponent();
         
            }

            private void OnSubmit(object sender, EventArgs e)
            {
                EntryCell entInput = new EntryCell
                {
                    Placeholder = "Name" 
                };
                string txt = "{Binding Name}";
                entInput.SetBinding(EntryCell.TextProperty, txt);
                SpouseTS.Add(entInput);
            }
        }
    }

Tab2.xaml

ontentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="FamTreeApp.Views.Tab2">
        <ContentPage.Content>
            <StackLayout>
                <Label Text="Welcome to Xamarin.Forms!"
                    VerticalOptions="CenterAndExpand" 
                    HorizontalOptions="CenterAndExpand" />
            </StackLayout>
        </ContentPage.Content>
    </ContentPage>

Tab2.xaml.cs

        public partial class Tab2 : ContentPage
    {
        public Tab2()
        {
            InitializeComponent();
        }
    }

ViewModelBase.cs

            public class ViewModelBase : BindableBase, INavigationAware
        {
            private readonly INavigationService navigationService;

            public ViewModelBase(INavigationService navigationService)
            {
                this.navigationService = navigationService;
            }

            private string title;
            public string Title
            {
                get => this.title;
                set => SetProperty(ref this.title, value);
            }

            public virtual void OnNavigatedFrom(INavigationParameters parameters) { }

            public virtual void OnNavigatedTo(INavigationParameters parameters) { }

            public virtual void OnNavigatingTo(INavigationParameters parameters) { }

           }

TabbedPageNavigationBehavior

            using Prism.Behaviors;
        using Prism.Common;
        using Prism.Navigation;
        using System;
        using System.Collections.Generic;
        using System.Text;
        using Xamarin.Forms;

        namespace FamTreeApp.Behaviors
        {

                public class TabbedPageNavigationBehavior : BehaviorBase<TabbedPage>
                {
                    private Page CurrentPage;

                    protected override void OnAttachedTo(TabbedPage bindable)
                    {
                        bindable.CurrentPageChanged += this.OnCurrentPageChanged;
                        base.OnAttachedTo(bindable);
                    }

                    protected override void OnDetachingFrom(TabbedPage bindable)
                    {
                        bindable.CurrentPageChanged -= this.OnCurrentPageChanged;
                        base.OnDetachingFrom(bindable);
                    }

                    private void OnCurrentPageChanged(object sender, EventArgs e)
                    {
                        var newPage = this.AssociatedObject.CurrentPage;

                        if (this.CurrentPage != null)
                        {
                            var parameters = new NavigationParameters();
                            PageUtilities.OnNavigatedFrom(this.CurrentPage, parameters);
                            PageUtilities.OnNavigatedTo(newPage, parameters);
                        }

                        this.CurrentPage = newPage;
                    }
                }

        }

Tab1Model.cs

        using Prism;
    using Prism.Navigation;
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Input;
    using Prism.Navigation.TabbedPages;
    using FamTreeApp.Models;
    using FamTreeApp.Views;

    namespace FamTreeApp.ViewModels
    {
        public class Tab1Model : ViewModelBase
        {
            public Tab1Model(INavigationService navigationService)
            : base(navigationService)
            {
                this.Title = nameof(Tab1);

            }


            public override void OnNavigatedFrom(INavigationParameters parameters)
            {
                base.OnNavigatedFrom(parameters);
     
                  **parameters.Add(nameof(this.Name), this.Name);**

            }

        }
    }

Tab2Model.cs

        using System;
    using System.Collections.Generic;
    using System.Text;
    //using FamTreeApp.ViewModels.FamTreeApp.Views;
    using Prism;
    using Prism.Navigation;
    //using FamTreeApp.ViewModels.FamTreeApp.Models;

    namespace FamTreeApp.ViewModels
    {
        namespace FamTreeApp.ViewModels
        {
            public class Tab2Models : ViewModelBase

            {

               private string name;
        
                public Tab2Models(INavigationService navigationService)
            : base(navigationService)
                {
                    //this.Title = nameof(Tab2);

                }

   
                public override void OnNavigatedFrom(INavigationParameters parameters)
                {
                    base.OnNavigatedFrom(parameters);
          
                }

            }


        }

    }

App.xaml.cs

        using Prism;
    using Prism.Ioc;
    using FamTreeApp.ViewModels;
    using FamTreeApp.Views;
    using Xamarin.Essentials.Interfaces;
    using Xamarin.Essentials.Implementation;
    using Xamarin.Forms;
    using Prism.DryIoc;
    using Prism.Navigation;

    using Xamarin.Forms.Xaml;

    namespace FamTreeApp
    {
        public partial class App : PrismApplication
        {
            public App() : this(null) { }

            public App(IPlatformInitializer initializer) : base(initializer) { }

            protected override async void OnInitialized()
            {
                InitializeComponent();
                await this.NavigationService.NavigateAsync(nameof(TabbedPage1));

            }

            protected override void RegisterTypes(IContainerRegistry containerRegistry)
            {
                containerRegistry.RegisterForNavigation<TabbedPage1>();
                containerRegistry.RegisterForNavigation<Tab1, Tab1Model>();
                containerRegistry.RegisterForNavigation<Tab2, Tab2Models>();

 
            }
        }

    }

How do I access the value of the EntryCell(created on the click of submit button) in its ViewModel - Tab1Models? Here I've used Prism, how can I accessed the value of the newly created EntryCell its custom ViewModel with or without Prism?

Upvotes: 0

Views: 203

Answers (1)

Jason
Jason

Reputation: 89102

first, you are not using SetBinding correctly

        private void OnSubmit(object sender, EventArgs e)
        {
            EntryCell entInput = new EntryCell
            {
                Placeholder = "Name" 
            };
            
            // bind to a property "Name"
            entInput.SetBinding(EntryCell.TextProperty, "Name");
            SpouseTS.Add(entInput);
        }

then in your VM you need a Name property

public class Tab1Model : ViewModelBase
    {
        public Tab1Model(INavigationService navigationService)
        : base(navigationService)
        {
            this.Title = nameof(Tab1);

        }

        public string Name { get; set; }

        public override void OnNavigatedFrom(INavigationParameters parameters)
        {
            base.OnNavigatedFrom(parameters);
 
            parameters.Add(nameof(this.Name), this.Name);
        }
    }

note that I am assuming you have your BindingContext set correctly or that Prism is doing it for you - I'm not familiar with how Prism handles that

Upvotes: 1

Related Questions