在打开的页面之间传递参数的最佳实践 [英] best practice to pass parameters between open pages

查看:20
本文介绍了在打开的页面之间传递参数的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个有两个页面的 Windows 应用程序 (UWP),我希望最佳实践是在页面之间传递参数.

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

这是我的场景:

我们有两个页面,每个页面都打开并保持在屏幕中间,每个页面上都有一个按钮,当我们点击它时,它会将消息发送到另一个页面.

We have two pages, each open and remain at the middle of the screen and a Button on each page, which send the message to the other page when we click on it.

我还想连续和重复地传递信息.

在 Page1.cs 中:

     Page2 page2;
         public Page1()
                {
                    this.InitializeComponent();         
                    CreatPage2();
                }

         // creat page 2
           private async void CreatPage2()
                {
                    var NewWindow = CoreApplication.CreateNewView();
                    int NewWindowid = 0;

                    await NewWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
                    {
                        Frame newframe = new Frame();
                        newframe.Navigate(typeof(Page2), this);
                        Window.Current.Content = newframe;
                        Window.Current.Activate();
                        ApplicationView.GetForCurrentView().Title = "page2";
                        NewWindowid = ApplicationView.GetForCurrentView().Id;
                    });

                    await Windows.UI.ViewManagement.ApplicationViewSwitcher.TryShowAsStandaloneAsync(NewWindowid);
                }

                //Button


     private void ChangeP2_Click(object sender, RoutedEventArgs e)
                {
                  // send a message to the texblock in the page2
        page2.TexBlock2.Text=$"From page1 :{e.ToString()}";
// change  text color of the texblock in the page2
page2.Foreground= new SolidColorBrush(Windows.UI.Colors.Red);
                }

在 Page2.cs 中:

  Page1 page1;
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        page1 = e.Parameter as Page1;
        base.OnNavigatedTo(e);
    }

    public Page2()
    {
        this.InitializeComponent();         
    }



    //Button
     private void ChangeP1_Click(object sender, RoutedEventArgs e)
    {
// send a message to the texblock in the page1
      page1.TexBlock1.Text=$"From page2 :{e.ToString()}";
// change  text color of the texblock in the page1
page1.Foreground= new SolidColorBrush(Windows.UI.Colors.Red);
    }

上面的代码只适用于 page2 到 page1.(它可以改变pagea的textblock).请帮帮我,我找不到适用于两页的解决方案

the above code just work for the page2 to the page1. (it can change the textblock of pagea). Please help me, I can't find a solution that work on two pages

推荐答案

不……最好的方法是使用由应用程序 ViewModel 类组成的标准模式,其中包含您想要在应用程序中使用的所有常见应用程序数据逻辑层.

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.

我总是这样做:

1) 我使用自动创建的 MainPage 作为应用程序的外壳",其属性为 AppViewModel.MainPage(以及 AppViewModel)可以从应用程序的任何地方访问,方法是在自己的类中将自身设置为静态字段.

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) AppViewModel 本身是一个必须实现 INotifyPropertyChanged 接口的类,以便启用可绑定的属性和功能.开发人员通常会创建一个实现它的基类,然后从中派生出所有需要可绑定属性的类.

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.

这是:

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;
    }
}

然后您从中派生 AppViewModel 类(以及所有其他模型和视图模型类)……用您需要跨页面共享的所有公共属性填充它.我什至添加了一个派生属性,以展示如何一次共享多种数据类型和一个函数:

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) 然后,为了从另一个 Page 访问所有这些,只需在该页面中创建一个 AppViewModel 字段,如下所示:

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();
    }
}

...并且您可以轻松地将 XAML 控件属性绑定到 AppViewModel 本身:

...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 用于实时绑定,以便即使在 UI 中也能立即更新属性,而 Mode=TwoWay 用于这些属性用户可以从控件本身进行编辑,以便与应用逻辑进行交互).

(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).

希望这有帮助.

最好的问候和新年快乐.

Best regards and happy new year.

这篇关于在打开的页面之间传递参数的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆