none
Xaml zwischen Seiten wechseln

    Frage

  • Hallo Forum,

    ich habe in VS ein Wpf Projekt und komme gerade nicht weiter.

    Und zwar habe ich das MainWindows und eine Page. Wenn auf dem MainWindow der entsprechende Button gedrückt wird soll die Seite angezeigt werden.

    Wie kann ich das im Button Click Event umsetzen. Im Internet finde ich Nichts was mir hilft.

    Danke

    Samstag, 18. Mai 2019 16:18

Antworten

  • Im Code Behind definierst du beim Button die Methode, welche beim Click-Event aufgerufen werden soll:

    <Button Content="Open new Window" Click="Button_Click"/>

    und im Code (MainWindow.xaml.cs) dann die Methode selbst:

    private void Button_Click(Object sender, RoutedEventArgs e)
    {
        new Window1().Show();
    }
    


    In MVVM benötigst du ein ViewModel mit einem Command und der Action zum Command

    public ICommand ButtonCommand { get; set; }

    public MainWindowViewModel()
    {
        ButtonCommand = new RelayCommand(ButtonClick);
    }

    private void ButtonClick() { new Window1().Show(); }

    Im XAML wiederum bindest du das ViewModel und das Command an den Button

        <Window.DataContext>
            <local:MainWindowViewModel />
        </Window.DataContext>
        <Grid>
            <Button Content="Open new Window" Command="{Binding ButtonCommand}" />
        </Grid>
    
    Der Weg über MVVM scheint erst einmal komplizierter; der Code (C# *und* XAML) ist hinterher aber (meiner Meinung nach) aufgeräumter.

    Montag, 20. Mai 2019 06:45
  • Hi,
    nachfolgend mal eine kleine MVVM-Demo, in der mit Klick im Menü eine entsprechende Seite (Page) im Fenster geladen wird.

    XAML:

    <Window x:Class="WpfApp1.Window33"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window33" Height="450" Width="800">
      <Window.DataContext>
        <local:Window33VM/>
      </Window.DataContext>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
          <RowDefinition/>
        </Grid.RowDefinitions>
        <Menu>
          <MenuItem Header="Page 1" Command="{Binding Cmd}" CommandParameter="Page1"/>
          <MenuItem Header="Page 2" Command="{Binding Cmd}" CommandParameter="Page2"/>
        </Menu>
        <Frame Grid.Row="1" Content="{Binding DisplayedPage}"/>
      </Grid>

    Code:

    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    
    namespace WpfApp1
    {
      public partial class Window33VM : INotifyPropertyChanged
      {
        private Page _displayedPage = null;
        public Page DisplayedPage
        {
          get { return this._displayedPage; }
          set
          {
            this._displayedPage = value;
            OnPropChanged();
          }
        }
        public ICommand Cmd { get { return new RelayCommand(CmdExec); } }
    
        private void CmdExec(object obj)
        {
          switch (obj.ToString())
          {
            case "Page1":
              DisplayedPage = new Window33Page1();
              break;
            case "Page2":
              DisplayedPage = new Window33Page2();
              break;
            default:
              break;
          }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        internal void OnPropChanged([CallerMemberName] string propName = "") =>
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
      }
    }
    

    Und dazu eine Beispiel-Page:

    <Page x:Class="WpfApp1.Window33Page1"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
          xmlns:local="clr-namespace:WpfApp1"
          mc:Ignorable="d" 
          d:DesignHeight="450" d:DesignWidth="800"
          Title="Window33Page1">
      <Grid>
        <TextBlock Text="Page 1"/>
      </Grid>
    </Page>


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Sonntag, 26. Mai 2019 08:10

Alle Antworten

  • Hi,
    arbeitest Du mit CodeBehind oder mit dem MVVM Entwurfsmuster?

    Bei Arbeit im CodeBehind brauchst Du nur das Click-Ereignis zu nutzen (im XAML).

    Bei Nutzung von MVVM suche mal nach der Relay-Klasse der Bindung der Command-Eigenschaft.


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Samstag, 18. Mai 2019 19:30
  • MVVM klappt bei mir nichts wirklich. Vllt. würde es klappen wenn ich ein Beispielprojekt hätte.

    Deswegen benutze ich Code Behind. Aber mich interessiert wie ich das in c# machen kann.

    Samstag, 18. Mai 2019 19:46
  • Im Code Behind definierst du beim Button die Methode, welche beim Click-Event aufgerufen werden soll:

    <Button Content="Open new Window" Click="Button_Click"/>

    und im Code (MainWindow.xaml.cs) dann die Methode selbst:

    private void Button_Click(Object sender, RoutedEventArgs e)
    {
        new Window1().Show();
    }
    


    In MVVM benötigst du ein ViewModel mit einem Command und der Action zum Command

    public ICommand ButtonCommand { get; set; }

    public MainWindowViewModel()
    {
        ButtonCommand = new RelayCommand(ButtonClick);
    }

    private void ButtonClick() { new Window1().Show(); }

    Im XAML wiederum bindest du das ViewModel und das Command an den Button

        <Window.DataContext>
            <local:MainWindowViewModel />
        </Window.DataContext>
        <Grid>
            <Button Content="Open new Window" Command="{Binding ButtonCommand}" />
        </Grid>
    
    Der Weg über MVVM scheint erst einmal komplizierter; der Code (C# *und* XAML) ist hinterher aber (meiner Meinung nach) aufgeräumter.

    Montag, 20. Mai 2019 06:45
  • Das funktioniert so, allerdings wird ein neues Fenster geöffnet. Ich habe aber eine Seite die im MainWindow angezeigt werden soll.
    Donnerstag, 23. Mai 2019 11:59
  • OK. Das kam in deiner Frage nicht so klar raus... du willst ein neues Fenster innerhalb deines MainWindows? Also im Grunde eine MDI-Anwendung erstellen?

    Für MDI mittels WPF gibt es einige Ansätze; such einfach mal nach diesen beiden Begriffen.

    Oder geht es nur um ein einzelnes (modal?) Fenster? Dann hilft vielleicht auch das hier ?

    Donnerstag, 23. Mai 2019 12:25
  • Meine Vorstellung war die:

    Ich hab das Main Windows und da wird ein Menu angezeigt(das hab ich auch schon so) und wenn man einen bestimmten Button drückt, soll statt dem Menu die eigentliche Anwendung angezeigt werden (ohne ein neues Fenster zu öffnen). Und diese eigentliche Anwendung ist auf einer Page, die dann eben im MainWindow angezeigt werden soll.

    Donnerstag, 23. Mai 2019 15:47
  • In dem Falle würde ich einfach ein Control (z.b. ein Grid in dem dann alles weitere liegt) in das Main Window setzen, welches im Bedarfsfalle ein- bzw. ausgeblendet wird.
    Freitag, 24. Mai 2019 05:54
  • und wie funktioniert das bei "richtigen" Anwendungen? Und wieso kann man in XAML dann überhaupt eine Page erstellen?
    Freitag, 24. Mai 2019 16:20
  • Hi,
    nachfolgend mal eine kleine MVVM-Demo, in der mit Klick im Menü eine entsprechende Seite (Page) im Fenster geladen wird.

    XAML:

    <Window x:Class="WpfApp1.Window33"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window33" Height="450" Width="800">
      <Window.DataContext>
        <local:Window33VM/>
      </Window.DataContext>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
          <RowDefinition/>
        </Grid.RowDefinitions>
        <Menu>
          <MenuItem Header="Page 1" Command="{Binding Cmd}" CommandParameter="Page1"/>
          <MenuItem Header="Page 2" Command="{Binding Cmd}" CommandParameter="Page2"/>
        </Menu>
        <Frame Grid.Row="1" Content="{Binding DisplayedPage}"/>
      </Grid>

    Code:

    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    
    namespace WpfApp1
    {
      public partial class Window33VM : INotifyPropertyChanged
      {
        private Page _displayedPage = null;
        public Page DisplayedPage
        {
          get { return this._displayedPage; }
          set
          {
            this._displayedPage = value;
            OnPropChanged();
          }
        }
        public ICommand Cmd { get { return new RelayCommand(CmdExec); } }
    
        private void CmdExec(object obj)
        {
          switch (obj.ToString())
          {
            case "Page1":
              DisplayedPage = new Window33Page1();
              break;
            case "Page2":
              DisplayedPage = new Window33Page2();
              break;
            default:
              break;
          }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        internal void OnPropChanged([CallerMemberName] string propName = "") =>
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
      }
    }
    

    Und dazu eine Beispiel-Page:

    <Page x:Class="WpfApp1.Window33Page1"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
          xmlns:local="clr-namespace:WpfApp1"
          mc:Ignorable="d" 
          d:DesignHeight="450" d:DesignWidth="800"
          Title="Window33Page1">
      <Grid>
        <TextBlock Text="Page 1"/>
      </Grid>
    </Page>


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Sonntag, 26. Mai 2019 08:10