locked
MVVM best practise to access pages elements in viewmodel RRS feed

  • Question

  • User369761 posted

    Hi Guys, i am new into mobile app developing and also into xamarin forms. i build a xamarin forms application and i try to use the mvvm pattern.

    What i try to achieve is like a simple form post in web developing.

    I have a ContentPage (MyPage.xaml) with multiple Entrys, a ViewModel (MyPageViewModel.cs) which is bound to the ContentPage and my code behind (MyPage.xaml.cs). As far as i understood all the business logic should be in the ViewModel.

    What i am now trying to do is reading all the data the user wrote into the entrys and afterwards i do whatever i want to do with this data. How can i access the view elements in my viewmodel?

    Or what is the best practice to work with the pages elements? In the code behind i can access them via this.findbyname("name").

    Thank you for your help, Gelatto

    Thursday, June 21, 2018 10:35 AM

Answers

  • User171749 posted

    To be able to access the views data, You will want to create a property in your ViewModel.

    For example, To get the Username from an Entry I would create property in ViewModel..

    CSHARP private string _username; public string Username { get { return _username; } set { _username = value; } }

    and then bind it to the TextProperty on the Entry field and I can access it from the ViewModel.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, June 21, 2018 11:01 AM
  • User89714 posted

    Don't forget the PropertyChanged event

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, June 21, 2018 11:10 AM

All replies

  • User364101 posted

    Suppose there is an entry in xaml page

    <Entry x:name="asd" />
    

    code behind

    string read;
    read=asd.text;
    

    You will get the text what user have written in Entry.

    Thursday, June 21, 2018 11:01 AM
  • User171749 posted

    To be able to access the views data, You will want to create a property in your ViewModel.

    For example, To get the Username from an Entry I would create property in ViewModel..

    CSHARP private string _username; public string Username { get { return _username; } set { _username = value; } }

    and then bind it to the TextProperty on the Entry field and I can access it from the ViewModel.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, June 21, 2018 11:01 AM
  • User89714 posted

    Don't forget the PropertyChanged event

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, June 21, 2018 11:10 AM
  • User369761 posted

    @JohnHardman what is this event about? do i implement it into my viewmodel? can you tell me how i implement it/how it works? Thanks

    Thursday, June 21, 2018 11:27 AM
  • User89714 posted

    @Gelatto - See https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm

    Thursday, June 21, 2018 11:33 AM
  • User369761 posted

    @JohnHardman @seanyda okay guys i now have implemented the properties in my viewmodel and i bound them to the xaml elements. i also got the nofifypropertychanged event running. works fine for except for labels where the bound property is of type decimal or an enum but the binding is set to the Text-Attribut of the Label. How does this work? Thx so much

    Thursday, June 21, 2018 12:45 PM
  • User171749 posted

    @Gelatto said: @JohnHardman @seanyda okay guys i now have implemented the properties in my viewmodel and i bound them to the xaml elements. i also got the nofifypropertychanged event running. works fine for except for labels where the bound property is of type decimal or an enum but the binding is set to the Text-Attribut of the Label. How does this work? Thx so much

    You would have to make a new property to handle the update. Here's an example from something I'm working on now.

    CSHARP private string statusToDisplay; public string StatusToDisplay { get { return statusToDisplay; } set { switch(Status) { case EventStatus.NotStarted: statusToDisplay = "Not Started"; break; case EventStatus.InProgress: statusToDisplay = "In Progress"; break; case EventStatus.Complete: statusToDisplay = "Complete"; break; } } }

    Thursday, June 21, 2018 12:47 PM
  • User89714 posted

    @Gelatto said: @JohnHardman @seanyda okay guys i now have implemented the properties in my viewmodel and i bound them to the xaml elements. i also got the nofifypropertychanged event running. works fine for except for labels where the bound property is of type decimal or an enum but the binding is set to the Text-Attribut of the Label. How does this work? Thx so much

    You use a Value Converter. See https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/converters

    Thursday, June 21, 2018 12:54 PM
  • User180523 posted

    access pages elements in viewmodel I'd stop you right there. A ViewModel should never be accessing UI elements. Period. It violates MVVM concept. If you start with the first foundation concept of MVVM you see why:

    A ViewModel can be the backing source for 0:n views.

    Meaning, that ViewModel for an Employee object might be the backing for one page... or 20 pages... or 10 pages and 2 ContentView sub-controls... Or no views whatsoever. So with that in mind... Which UI element on which view do you think the VIewModel should be trying to access? The answer is: none of them. Because the View and the ViewModel should never have that kind of tighly-coupled association.

    Thursday, June 21, 2018 1:27 PM
  • User382545 posted

    I use it like this

    private MyType _NameIWant;
    
            public MyType NameIWant
            {
                get
                {
                    return _NameIWant;
                }
    
                set
                {
                    _NameIWant = value;
                    OnPropertyChanged("NameIWantForBinding"); <---- Bindable in my xaml with this 
            ###Code you want when property changes
                }
            }
    
    Wednesday, February 20, 2019 5:44 PM