Могу ли я использовать кнопку с обработчиком событий, чтобы отправить пользователя в другой сценарий xaml? - PullRequest
1 голос
/ 03 ноября 2019

Я сделал игру на память с меню «Пуск» и отдельной страницей, где происходит игра. В главном меню вы можете выбрать свою тему и нажать кнопку, чтобы перейти в игру. У меня также есть кнопка на экране игры, но я не могу понять, как сделать так, чтобы она указывала на главное меню.

Честно говоря, я не знаю, как это сделать.

Это кнопка, которая ссылается с главной страницы на игру (в xaml):

<Button DockPanel.Dock="Top" Padding="25" Click="Play_Clicked" Background="#FF0E0E0E" Foreground="#FFF3FF00" FontSize="18">Start Game</Button>

это код в xaml.cs:

private void Play_Clicked(object sender, RoutedEventArgs e)
        {
            var startMenu = DataContext as StartMenuViewModel;
            startMenu.StartNewGame(categoryBox.SelectedIndex);
        }

Этокод из «StartMenuViewModel», который содержит «StartNewGame»:

public void StartNewGame(int categoryIndex)
{
    var category = (SlideCategories)categoryIndex;
    GameViewModel newGame = new GameViewModel(category);
    _mainWindow.DataContext = newGame;
}

Этот код работает, кто-нибудь знает, как сделать аналогичную кнопку для перехода с экрана игры в главное меню?

1 Ответ

1 голос
/ 03 ноября 2019

Самый простой и легкий способ использования Frame - создать модель представления для каждой страницы. Затем создайте модель основного вида, которая содержит все страницы и управляет их выбором. ContentControl будет отображать модели представлений, используя DataTemplate, назначенный свойству ContentControl.ContentTemplate, или в многостраничном сценарии либо DataTemplateSelector, назначенный ContentControl.ContentTemplateSelector, либо неявные шаблоны, только определяя DataTemplate.DataType без Key атрибут:

Представление

MainWindow.xaml

<Window>
  <Window.DataContext>
    <MainViewModel x:Key="MainViewModel" />
  </Window.DataContext>
  <Window.Resources>
    <!-- 
        The templates for the view of each page model.
        Can be moved to dedicated files.
    -->
    <DataTemplate DataType="{x:Type PageA}">
      <Border Background="Coral">
        <TextBlock Text="{Binding Title}" />
      </Border>
    </DataTemplate>

    <DataTemplate DataType="{x:Type PageB}">
      <Border Background="DeepSkyBlue">
        <TextBlock Text="{Binding Title}" />
      </Border>
    </DataTemplate>    
  </Window.Resources>


<StackPanel>
    <Button Content="Load Page A"
            Command="{Binding SelectPageFromIndexCommand}"
            CommandParameter="0" />
    <Button Content="Load Page B"
            Command="{Binding SelectPageFromIndexCommand}"
            CommandParameter="1" />

    <!-- The actual page control -->
    <ContentControl Content="{Binding SelectedPage}" />
  </StackPanel>
</Window>

Модель представления

MainViewModel. cs

class MainViewModel : INotifyPropertyChanged
{
  public MainViewModel()
  {
    this.Pages = new ObservableCollection<IPage>() {new PageA() {Title = "Page A"}, new PageB() {Title = "Page B"}};

    // Show startup page
    this.SelectedPage = this.Pages.First();
  }

  // Define the Execute and CanExecute delegates for the command
  // and pass to constructor
  public ICommand SelectPageFromIndexCommand => new SelectPageCommand(
    param => this.SelectedPage = this.Pages.ElementAt(int.Parse(param as string)),
    param => int.TryParse(param as string, out int index));

  private IPage selectedPage;    
  public IPage SelectedPage
  {
    get => this.selectedPage;
    set
    {
      if (object.Equals(value, this.selectedPage))
      {
        return;
      }

      this.selectedPage = value;
      OnPropertyChanged();
    }
  }

  private ObservableCollection<IPage> pages;    
  public ObservableCollection<IPage> Pages
  {
    get => this.pages;
    set
    {
      if (object.Equals(value, this.pages))
      {
        return;
      }

      this.pages = value;
      OnPropertyChanged();
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;    
  protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

SelectPageCommand.cs

class SelectPageCommand : ICommand
{
  public SelectPageCommand(Action<object> executeDelegate, Predicate<object> canExecuteDelegate)
  {
    this.ExecuteDelegate = executeDelegate;
    this.CanExecuteDelegate = canExecuteDelegate;
  }

  private Predicate<object> CanExecuteDelegate { get; }
  private Action<object> ExecuteDelegate { get; }

  #region Implementation of ICommand

  public bool CanExecute(object parameter) => this.CanExecuteDelegate?.Invoke(parameter) ?? false;

  public void Execute(object parameter) => this.ExecuteDelegate?.Invoke(parameter);

  public event EventHandler CanExecuteChanged
  {
    add => CommandManager.RequerySuggested += value;
    remove => CommandManager.RequerySuggested -= value;
  }

  #endregion
}

Модели страниц

IPage.cs

// Base type for all pages
interface IPage : INotifyPropertyChanged
{
  string Title { get; set; }
}

PageA.cs

// IPage implementation. 
// Consider to introduce dedicated interface IPageA which extends IPage
class PageA : IPage
{
  public string Title { get; set; }

  // Implementation of INotifyPropertyChanged
}

PageB.cs

// IPage implementation. 
// Consider to introduce dedicated interface IPageB which extends IPage
class PageB : IPage
{
  public string Title { get; set; }

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