best practice to pass parameters between open pages

后端 未结 1 1539
清酒与你
清酒与你 2021-01-26 22:38

I\'m developing a Windows application (UWP) that has two pages, I want the best practice to pass parameters between pages.

it\'s my scenario:

We have two pages,

相关标签:
1条回答
  • 2021-01-26 22:52

    Naah… the best way is to use a standard pattern that consist of an app ViewModel class, which contains all the common app data that you want to use in the logic layer.

    I always do it like this:

    1) I use the MainPage automatically created as the "shell" of the app, with a property that is the AppViewModel. The MainPage (and thus the AppViewModel) can be accessed from everywhere in the app, by setting itself as a static field in its own class.

    This is the code, simpler than you think:

    public sealed partial class MainPage : Page
    {
        public AppViewModel ViewModel { get; set; } = new AppViewModel();
        public static MainPage Current { get; set; }
    
        public MainPage()
        {
            this.InitializeComponent();
            Current = this;
        }
    }
    

    2) The AppViewModel itself is a class that must implement the INotifyPropertyChanged interface, in order to enable bindable properties and functions. It is common, among developers, to create a base class that implements it and then derive all the classes that needs bindable properties from it.

    Here it is:

    public class BaseBind : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        public void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    
        protected bool SetProperty<T>(ref T storage, T value,
            [CallerMemberName] String propertyName = null)
        {
            if (object.Equals(storage, value)) return false;
            storage = value;
            OnPropertyChanged(propertyName);
            return true;
        }
    }
    

    Then you derive AppViewModel class (and all the other model and viewmodel classes) from it… populating it with all the common properties that you need to share across pages. I have even added a derived property, in order to show how you can share even multiple data types at once, and a function:

    public class AppViewModel : BaseBind
    {
        public AppViewModel()
        {
            // ...
        }
    
        // All common app data
        private string sampleCommonString;
        public String SampleCommonString
        {
            get { return sampleCommonString; }
            set { SetProperty(ref sampleCommonString, value); OnPropertyChanged(nameof(SampleDerivedProperty1)); OnPropertyChanged(nameof(SampleDerivedProperty2)); }
        }
    
        public String SampleDerivedProperty1 =>  "return something based on SampleCommonString";
    
        public String SampleDerivedProperty2
        {
            get
            {
                <<evaluate SampleCommonString>>
                return "Same thing as SampleDerivedProperty1, but more explicit";
            }
        }
    
        // This is a property that you can use for functions and internal logic… but it CAN'T be binded
        public String SampleNOTBindableProperty { get; set; }
    
        public void SampleFunction()
        {
            // Insert code here.
    
            // The function has to be with NO parameters, in order to work with simple {x:Bind} markup.
            // If your function has to access some specific data, you can create a new bindable (or non) property, just as the ones above, and memorize the data there.
        }
    }
    

    3) Then, in order to access all this from another Page, just create an AppViewModel field in that page, as seen below:

    public sealed partial class SecondPage : Page
    {
        public AppViewModel ViewModel => MainPage.Current.ViewModel;
    
        public SecondPage()
        {
            this.InitializeComponent();
        }
    }
    

    ...and you can easily bind XAML controls properties to the AppViewModel itself:

    <TextBlock Text="{x:Bind ViewModel.SampleCommonString, Mode=OneWay}"/>
    <Button Content="Sample content" Click="{x:Bind ViewModel.SampleFunction}"/>
    

    (Mode=OneWay is for real-time binding, in order that the property is immediately updated even in the UI, while Mode=TwoWay is used for those properties that can be edited from the control itself, by the user, in order to interact with app logic).

    Hope this helped.

    Best regards and happy new year.

    0 讨论(0)
提交回复
热议问题