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