Есть много решений этой проблемы. Самое простое решение - использовать модель общего представления как для windows, так и для привязки данных. Поскольку оба windows будут совместно использовать один и тот же DataContext
, оба будут иметь доступ к одним и тем же данным или экземпляру модели, просто ссылаясь на их свойство DataContext
.
Но если вы предпочитаете иметь отдельные модели представления, вы бы выберите другое решение.
Решение 1
Если вы хотите использовать выделенную модель представления для каждого окна, вы всегда можете использовать композицию и сделать, например, экземпляр SaveGameViewModel
членом MainWindowViewModel
. Любой класс, имеющий доступ к MainWindowViewModel
, также будет иметь доступ к SaveGameViewModel
и его API, либо напрямую, либо через делегирование свойств.
В этом примере используется прямой доступ, предоставив SaveGameViewModel
в качестве свойства publi c для MainWindowViewModel
:
SaveGameViewModel.cs
public class SaveGameViewModel : INotifyPropertyChanged
{
private string name;
public string Name
{
get => this.name;
set
{
this.name = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
MainWindowViewModel.cs
public class MainWindowViewModel : INotifyPropertyChanged
{
public SaveGameViewModel SaveGameViewModel { get; set; }
// Allow to create an instance using XAML
public MainWindowViewModel() {}
// Allow to create an instance using C#
public MainWindowViewModel(SaveGameViewModel saveGameViewModel)
=> this.SaveGameViewModel = saveGameViewModel;
}
App .xaml
<Application>
<Application.Resources>
<MainWindowViewModel x:Key="MainWindowViewModel">
<MainWindowViewModel.SaveGameViewModel>
<SaveGameViewModel />
</MainWindowViewModel.SaveGameViewModel>
</MainWindowViewModel>
</Application.Resources>
</Application>
SaveGameWindow.xaml
<Window DataContext="{Binding Source={StaticResource MainWindowViewModel}, Path=SaveGameViewModel}">
<TextBox Text="{Binding Name}" />
<Window>
MainWindow.xaml
<Window DataContext="{StaticResource MainWindowViewModel}">
<Window>
MainWindow.xaml.cs
partial class MainWindow : Window
{
private void OnKeyPressed(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
var mainWindowViewModel = this.DataContext as MainWindowViewModel;
string saveGameName = mainWindowViewModel.SaveGameViewModel.Name;
}
}
}
Решение 2
Поскольку вы просто показываете диалог, вы можете сохранить текущий экземпляр SaveGameViewModel
или интересующие его значения после закрытия диалогового окна:
MainWindow.xaml.cs
partial class MainWindow : Window
{
private SaveGameViewModel CurrentSaveGameViewModel { get; set; }
private bool IsSaveGameValid { get; set; }
private void ShowDialog_OnSaveButtonClick(object sender, RoutedEventArgs e)
{
var saveGameDialog = new SaveGameWindow();
this.IsSaveGameValid = saveGameDialog.ShowDialog ?? false;
this.CurrentSaveGameViewModel = saveGameDialog.DataContext as SaveGameViewModel;
}
private void OnKeyPressed(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape && this.IsSaveGameValid)
{
string saveGameName = this.CurrentSaveGameViewModel.Name;
}
}
}
MainWindow.xaml
<Window>
<Window.DataContext>
<MainWindowViewModel />
</Window.DataContext>
<Window>
SaveGameWindow.xaml
<Window>
<Window.DataContext>
<SaveGameViewModel />
</Window.DataContext>
<TextBox Text="{Binding Name}" />
<Window>