Databinding between two views in Xamarin

Jürgen Keitzl 61 Reputation points
2021-12-30T11:02:56.067+00:00

Hello,

I'm not a professional developer, I'm more a hobbyies and started with .net and Xamarin weeks ago.

For me is it interessting to understand how software works. For that I try to reengineer existing solutions. At the moment I fail at the databinding between to views.
Short description:

161394-screenshot-2021-12-30-124351.png

I don't get the data from ViewOne to ViewTwo and also not from ViewTwo to ViewOne.

What I did.

Bind Command for button in VM1 and a method to assign date to property (works) and open ViewTwo

Bind Command for button(done) in VM2 and a method to assign additional values to properties in VM1 (don't work) and open ViewOne

Bind ViewOne to VM1, (Entry Text bind to Property Text. That works.
Bind ViewTwo to VM1( bind Label Text to property Text in VM1) -> no Data in ViewTwo Label.
Bind Entry1 and Entry2 in ViewTwo to Property Text2 and Text3 in VM1 ( No data in property Text2, Text3 after pressed Done.

the model is for saving data in database.

Mybe I have a general understanding problem how binding works in relation to different views.

But I'm grateful for any tip or help.

Best Regards
Juergen

Developer technologies .NET Xamarin
0 comments No comments
{count} votes

Accepted answer
  1. Anonymous
    2022-01-03T07:55:52.297+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    . What I want is to bind one VM to two Views like in the picture.

    If so, you need to create static ViewModel like following code. For example, you want VIew1 and view2 binding Page1VM.

       public static class ViewModelLocator  
           {  
               private static Page1VM _myViewModel = new Page1VM();  
               public static Page1VM MainViewModel  
               {  
                   get  
                   {  
                       return _myViewModel;  
                   }  
               }  
           }  
    

    Here is view1's layout. I delete the ContentPage.BindingContext, I bind it in the layout background code.

       <ContentPage.ToolbarItems>  
               <ToolbarItem Text="Add" Command="{Binding AddItemCommand}" />  
           </ContentPage.ToolbarItems>  
         
           <ContentPage.Content>  
               <StackLayout>  
                   <Entry x:Name="Entry" Text="{Binding Cat1, Mode=TwoWay}"  
                            
                           WidthRequest="100"  
                           BackgroundColor="Aqua"/>  
                   <Label Text="{Binding Text1  }" BackgroundColor="Gold" WidthRequest="100"/>  
               </StackLayout>  
           </ContentPage.Content>  
    

    Here is view1's background code. add BindingContext like following code.

       public partial class AboutPage : ContentPage  
           {  
               public AboutPage()  
               {  
                   InitializeComponent();  
         
                   BindingContext = ViewModelLocator.MainViewModel;  
         
               }  
           }  
    

    In the view2, we need to delete the ContentPage.BindingContext as well, I also bind it in the layout background code.

       <ContentPage.Content>  
               <StackLayout>  
                   <Label  BackgroundColor="Beige" WidthRequest="100" Text="{Binding Cat1, Mode=TwoWay}" />  
                   <Entry Text="{Binding OwnerFirstN , Mode=TwoWay}"/>  
                   <Entry Text="{Binding OwnerLastN, Mode=TwoWay}"/>  
                   <Entry Text="{Binding SicknessCat1, Mode=TwoWay}">  
                       <Entry.BindingContext>  
                           <vm:Page2VM/>  
                       </Entry.BindingContext>  
                   </Entry>  
         
               </StackLayout>  
           </ContentPage.Content>  
    

    Here is view2's layout background code.

       public partial class Page2 : ContentPage  
           {  
               public Page2()  
               {  
                   InitializeComponent();  
         
                   BindingContext = ViewModelLocator.MainViewModel;  
         
               }  
           }  
    

    Happy new year.

    Best Regards,

    Leon Lu


    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.


3 additional answers

Sort by: Most helpful
  1. Anonymous
    2021-12-31T03:14:57.303+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    Based on your description. you want to binding two view model for one view, am I right?

    If so, you can use this way to binding other local:ViewModel2 <Label BindingContext="{Binding Source ={local:ViewModel2}}" Text="{Binding DogName}" />

    For example, you have two viewmodel called ViewModel1(include a property called catName) and ViewModel2(include a property called dogName).

       public class ViewModel1: BaseViewModel  
           {  
               private string catName;  
               public string CatName  
               {  
                   get => catName;  
                   set  
                   {  
                       catName = value;  
                       OnPropertyChanged(nameof(CatName));  
                   }  
               }  
               public ViewModel1()  
               {  
                   CatName = "Kitty";  
               }  
           }  
         
           public class ViewModel2 : BaseViewModel  
           {  
               private string dogName;  
               public string DogName  
               {  
                   get => dogName;  
                   set  
                   {  
                       dogName = value;  
                       OnPropertyChanged(nameof(DogName));  
                   }  
               }  
               public ViewModel2()  
               {  
                   DogName = "Doggy";  
               }  
           }  
    

    Then I have page that binding viewmodel1 in the background code.

       public MainPage()  
               {  
                   InitializeComponent();  
         
                   ViewModel1 ViewModel1 = new ViewModel1();  
         
                
                   BindingContext = ViewModel1;  
                   
               }  
    

    If I want to show a dogName in Label from ViewModel2, we binding it like following xaml. Please notice you need add xmlns:local prefix in the <ContentPage >.

       <?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="InfraRedDependenceService.MainPage"  
                      
                    xmlns:local="clr-namespace:InfraRedDependenceService"   
                  
                    >  
         
           <StackLayout>  
         
         
               <Label   Text="{Binding CatName}"></Label>  
         
         
               <Label   BindingContext="{Binding Source ={local:ViewModel2}}" Text="{Binding DogName}" />  
         
         
                 
           </StackLayout>  
         
       </ContentPage>  
    

    Best Regards,

    Leon Lu


    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.

    0 comments No comments

  2. Jürgen Keitzl 61 Reputation points
    2022-01-01T14:08:37.59+00:00

    Hello Leon,

    thanks for your suggestion. What I want is to bind one VM to two Views like in the picture.

    in the code is my idea for that. but it didn't works. After he change to the new View the the properties are not binded.

    I hope the sketch and the code clarify it some more.

    161686-screenshot-2022-01-01-143613.jpg

      public class Page1VM : INotifyPropertyChanged  
        {  
           public event PropertyChangedEventHandler PropertyChanged;  
      
            private string cat1;  
            public string Cat1  
            {  
                get { return cat1; }  
                set { cat1 = value;  
                    OnPropertyChanged(); }  
            }  
      
            private string ownerFirstN;  
      
            public string OwnerFirstN  
            {  
                get { return ownerFirstN; }  
                set { ownerFirstN = value;  
                    OnPropertyChanged();  
                }  
            }  
      
            private string ownerLastN;  
      
            public string OwnerLastN  
            {  
                get { return ownerLastN; }  
                set { ownerLastN = value;  
                    OnPropertyChanged();  
                }  
            }  
      
            protected void OnPropertyChanged([CallerMemberName] string name = null)  
            {  
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));  
            }  
            public Command AddItemCommand { get; }  
      
            public Page1VM()  
            {  
                AddItemCommand = new Command(OnAddItem);  
            }  
      
            private async void OnAddItem(object obj)  
            {  
                await Shell.Current.GoToAsync(nameof(Page2));  
            }  
      
      <ContentPage.BindingContext>  
            <vm:Page1VM/>  
        </ContentPage.BindingContext>  
      
      
        <ContentPage.ToolbarItems>  
            <ToolbarItem Text="Add" Command="{Binding AddItemCommand}" />  
        </ContentPage.ToolbarItems>  
      
        <ContentPage.Content>  
            <StackLayout>  
                <Entry x:Name="Entry" Text="{Binding Cat1, Mode=TwoWay}"  
                     
                       WidthRequest="100"  
                       BackgroundColor="Aqua"/>  
                <Label Text="{Binding Text1 , Mode=TwoWay}" BackgroundColor="Gold" WidthRequest="100"/>  
            </StackLayout>  
        </ContentPage.Content>  
    
    
    
     public class Page2VM : INotifyPropertyChanged  
        {  
            public event PropertyChangedEventHandler PropertyChanged;  
                
            private string siknessCat1;  
            public string SicknessCat1  
            {  
                get { return sicknessCat1; }  
                set  
                {  
                    sicknessCat1=value;  
                    OnPropertyChanged();  
                }  
            }  
      
            protected void OnPropertyChanged([CallerMemberName] string name = null)  
            {  
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));  
            }  
      
            public Page2VM ()  
            {  
             
            }  
        }  
    
     <ContentPage.BindingContext>  
            <vm:Page1VM/>  
        </ContentPage.BindingContext>  
      
        <ContentPage.Content>  
            <StackLayout>  
                <Label  BackgroundColor="Beige" WidthRequest="100" Text="{Binding Cat1 , Mode=TwoWay}"/>  
                <Entry Text="{Binding OwnerFirstN , Mode=TwoWay}"/>  
                <Entry Text="{Binding OwnerLastN, Mode=TwoWay}"/>  
                <Entry Text="{Binding SicknessCat1, Mode=TwoWay}">  
                   <Entry.BindingContext>  
                        <local:Page2VM/>  
                    </Entry.BindingContext>  
                </Entry>  
                         
            </StackLayout>  
        </ContentPage.Content>  
    

  3. Jürgen Keitzl 61 Reputation points
    2022-01-05T12:06:51.9+00:00

    Hey Leon,

    thank you very much for your help. Is works perfect.

    Juergen

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.