лучшая практика для передачи параметров между открытыми страницами - PullRequest
0 голосов
/ 06 января 2019

Я занимаюсь разработкой приложения для Windows (UWP), которое состоит из двух страниц, и я хочу, чтобы передовой метод передавал параметры между страницами.

это мой сценарий:

У нас есть две страницы, каждая открыта и остается в середине экрана и кнопка на каждой странице, которая отправляет сообщение на другую страницу, когда мы нажимаем на нее.

Я также хочу передавать информацию непрерывно и многократно.

в 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. (это может изменить текстовый блок страницы). Пожалуйста, помогите мне, я не могу найти решение, которое работает на двух страницах

1 Ответ

0 голосов
/ 06 января 2019

Нах ... лучший способ - использовать стандартный шаблон, состоящий из класса приложения ViewModel, который содержит все общие данные приложения, которые вы хотите использовать на уровне логики.

Я всегда так делаю:

1) Я использую MainPage, автоматически созданную в качестве «оболочки» приложения, со свойством AppViewModel. MainPage (и, следовательно, AppViewModel) может быть доступен из любого места приложения, устанавливая себя как статическое поле в своем собственном классе.

Это код, который проще, чем вы думаете:

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, чтобы включить привязываемые свойства и функции. Разработчики часто создают базовый класс, который его реализует, а затем извлекают из него все классы, для которых нужны привязываемые свойства.

Вот оно:

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 (и все другие классы модели и модели представления) из него ... заполняя его всеми общими свойствами, которые вы хотите использовать на всех страницах. Я даже добавил производное свойство, чтобы показать, как вы можете совместно использовать даже несколько типов данных одновременно, и функцию:

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 на этой странице, как показано ниже:

public sealed partial class SecondPage : Page
{
    public AppViewModel ViewModel => MainPage.Current.ViewModel;

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

... и вы можете легко связать свойства элементов управления XAML с самим AppViewModel:

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

(Mode=OneWay для привязки в реальном времени, чтобы свойство немедленно обновлялось даже в пользовательском интерфейсе, в то время как Mode=TwoWay используется для тех свойств, которые пользователь может редактировать из самого элемента управления в для взаимодействия с логикой приложения).

Надеюсь, это помогло.

С наилучшими пожеланиями и счастливого нового года.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...