How to change the UI when the model's view property changes?

Влад Тигинян 40 Reputation points
2023-06-01T08:55:34.15+00:00

Hi all. Recently I started to study the mvvm pattern and ran into a problem. How to change the UI when the model's view property changes?

There is a model

    public class Setting
    {
        public string AliasCertificate { get; set; } = string.Empty;

        public Setting(string alias)
        {
            AliasCertificate = alias;
        }
    }

I have a view model

public partial class SettingsViewModel : INotifyPropertyChanged
    {
        string aliasCertificate = "";
        public event PropertyChangedEventHandler PropertyChanged;
        public ICommand ChooseCertificateCommand { get; set; }
        public ICommand AddAliasCommand { get; set; }
        public ICommand TestCommand { get; }

        public SettingsViewModel()
        {
            try
            {
                string s = Preferences.Default.Get("alias", "null");

                if (s.Equals("null"))
                    return;
                AliasCertificate = s;
            }
            catch (Exception ex)
            {

            }
            ChooseCertificateCommand = new Command(async () =>
            {
                try
                {
                    ICertificateInfo certificateInfo = DependencyService.Get<ICertificateInfo>();
                    certificateInfo.ChooseCertificate();
                }
                catch (Exception exception)
                {
                    //await DisplayAlert("Внимание", $"{exception.Message}{System.Environment.NewLine}{exception.StackTrace}", "OK");
                    await exception.SaveExceptionAsync(Repositories.Logs.LogWarningLevel.Critical, "OnExceptionChooseCertificate");
                }
            });
        }

        public string AliasCertificate
        {
            get => aliasCertificate;
            set
            {
                aliasCertificate = value;
                OnPropertyChanged(AliasCertificate);
            }
        }

        private void OnPropertyChanged([CallerMemberName] string prop = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
        }
    }

My view

<Label
                                FontSize="14"
                                FontAttributes="Bold"
                                TextColor="Black"
                                Text="{Binding AliasCertificate}"
                                x:Name="lblAliasCertificate"/>

With the command, I select the certificate alias and save it, and also try to display it in the view through the view property of the model, but the UI does not change.

public async void Alias(string alias)
	{

		bool hasKey = Preferences.Default.ContainsKey("alias");

        if (hasKey)
            Preferences.Default.Remove("alias");
        Preferences.Default.Set("alias", alias);

            // TODO change property in SettingsViewModel
            SettingsViewModel viewModel = new SettingsViewModel();
            viewModel.AliasCertificate = alias;
	}

What is the correct way to change the user interface through the view property of the model? I will be grateful for any answer.

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,632 questions
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,216 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,635 questions
{count} votes

Accepted answer
  1. Wenyan Zhang (Shanghai Wicresoft Co,.Ltd.) 29,301 Reputation points Microsoft Vendor
    2023-06-02T06:55:36.64+00:00

    Hello,

    Firstly, you could replace the AliasCertificate property with the following code:

    public string AliasCertificate
        {
            get => aliasCertificate;
            set
            {
                if (aliasCertificate != value)
                {
                    aliasCertificate = value;
                    OnPropertyChanged("AliasCertificate");// you can see the OnPropertyChanged method, the parameter should be the property name not property itself. Or you can call OnPropertyChanged() to report this property.
                }  
            }
        }
    

    Besides, I'm not sure how you set the SettingsViewModel as BindingContext of your Page. From the code snippets (SettingsViewModel viewModel = new SettingsViewModel(); viewModel.AliasCertificate = alias;), I can see you create a new SettingsViewModel, then set a new value for AliasCertificate. You should find the binding context of the Page (object), then set a new value.

    For example:

    <ContentPage ...
                 x:Class="XXX.MainPage"
                 xmlns:local ="clr-namespace:XXX">
        <ContentPage.BindingContext>
            <local:SettingsViewModel></local:SettingsViewModel>
        </ContentPage.BindingContext>
    
    <Label ...
                   Text="{Binding AliasCertificate}"
                    />
                <Button
                   ...
                   Command="{Binding AddAliasCommand}"
                   Clicked="OnCounterClicked" />
    ...
    

    OnCounterClicked Method

    private void OnCounterClicked(object sender, EventArgs e)
        {
            string alias = "alias" + count.ToString();
            bool hasKey =...
            SettingsViewModel viewModel = this.BindingContext as SettingsViewModel;
            viewModel.AliasCertificate = alias;
        }
    

    Or modify the AddAliasCommand (If you bind command, the clicked method won't be triggered)

    public SettingsViewModel()
        {
           AddAliasCommand = new Command( () =>
            {...
                string alias = "123"
                this.AliasCertificate = alias;
            });
       }
    

    About MVVM and Data Binding, you could see:

    Data binding basics - .NET MAUI | Microsoft Learn

    Data binding and MVVM - .NET MAUI | Microsoft Learn

    Model-View-ViewModel (MVVM) pattern

    And there is a MVVM training for Xamarin.Forms, it applies to MAUI: Design an MVVM viewmodel for Xamarin.Forms - Training | Microsoft Learn

    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.

    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful