Benutzer mit den meisten Antworten
Navigation von Page zu Frame

Frage
-
Hallo zusammen,
ich arbeite mich gerade in WPF C# ein und bin jetzt auf ein Problem gestoßen wobei ich nicht weiter komm.
Ich habe ein Hauptfenster (Main) in welchem sich ein Stackpanel auf der linken Seite für die Buttons (Button1 - 6) zur Navigation befindet und ein Frame zur Darstellung der Pages (Page1 -6) welche von den Buttons angewählt werden. (eine Art Dashboard).
Wenn ich dann den Button1 anklicke, öffne ich über (Frame.NavigationService.Navigate(Page1()); die Page1 in dem Frame, welches auch super funktioniert.
Wenn ich aber in der Page1 (welches im Frame geöffnet ist) auf einen Button klicke um eine andere Page (z.B. Page7) finde ich keine Möglichkeit wie ich diese Page im Frame öffnen kann.
Hab es versucht mit:
Main _Main = new Main();
_Main.Frame.NavigationService.Navigate(Page7());
allerdings funktioniert das nicht.
Hätte vieleicht jemand ne Idee oder nen Vorschlag, wie ich dies lösen kann?
Danke schon mal.
Antworten
-
Hi,
Du kannst dem Frame einen anderen Content zuweisen. Hier mal eine Demo mit ViewModel, der sowohl vom Main-Window als auch von den Pages genutzt wird. Bei jedem Klick wird aber eine neue Page-Instanz erzeugt. Falls Du es anders haben willst, müsstest Du Dir die Instanzen merken, z.B. in einem Dictionary.XAML:
<Window x:Class="WpfApp1CS.Window29" 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:WpfApp1CS" mc:Ignorable="d" Title="Window29" Height="300" Width="300"> <Window.Resources> <local:Window29VM x:Key="vm"/> <Style TargetType="Button"> <Setter Property="Margin" Value="5"/> </Style> </Window.Resources> <Grid DataContext="{StaticResource vm}"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <StackPanel Margin="5"> <Button Content="Page 1" Command="{Binding Cmd}" CommandParameter="Page 1"/> <Button Content="Page 2" Command="{Binding Cmd}" CommandParameter="Page 2"/> </StackPanel> <Frame Grid.Column="1" Margin="10" Content="{Binding ActualPage}" /> </Grid> </Window>
XAML eine Page:
<Page x:Class="WpfApp1CS.Window29Page1" 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:WpfApp1CS" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Title="Window29Page1"> <StackPanel> <Label Content="Page 1"/> <Button Content="Page 2" Command="{Binding Cmd}" CommandParameter="Page 2"/> </StackPanel> </Page>
Und dazu der ViewModel:
using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace WpfApp1CS { public class Window29VM:INotifyPropertyChanged { public Page ActualPage { get; set; } public ICommand Cmd { get { return new RelayCommand(CmdExec); } } private void CmdExec(object obj) { switch (obj.ToString()) { case "Page 1": ActualPage = new Window29Page1(); break; case "Page 2": ActualPage = new Window29Page2(); break; } ActualPage.DataContext = this; OnPropertyChanged(nameof(ActualPage)); } #region OnPropertyChanged public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); #endregion } }
--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks- Bearbeitet Peter Fleischer Sonntag, 21. Januar 2018 10:22
- Als Antwort vorgeschlagen Ivan DragovMicrosoft contingent staff, Moderator Donnerstag, 25. Januar 2018 07:59
- Als Antwort markiert Ivan DragovMicrosoft contingent staff, Moderator Freitag, 2. Februar 2018 06:20
Alle Antworten
-
Hi,
Du kannst dem Frame einen anderen Content zuweisen. Hier mal eine Demo mit ViewModel, der sowohl vom Main-Window als auch von den Pages genutzt wird. Bei jedem Klick wird aber eine neue Page-Instanz erzeugt. Falls Du es anders haben willst, müsstest Du Dir die Instanzen merken, z.B. in einem Dictionary.XAML:
<Window x:Class="WpfApp1CS.Window29" 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:WpfApp1CS" mc:Ignorable="d" Title="Window29" Height="300" Width="300"> <Window.Resources> <local:Window29VM x:Key="vm"/> <Style TargetType="Button"> <Setter Property="Margin" Value="5"/> </Style> </Window.Resources> <Grid DataContext="{StaticResource vm}"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <StackPanel Margin="5"> <Button Content="Page 1" Command="{Binding Cmd}" CommandParameter="Page 1"/> <Button Content="Page 2" Command="{Binding Cmd}" CommandParameter="Page 2"/> </StackPanel> <Frame Grid.Column="1" Margin="10" Content="{Binding ActualPage}" /> </Grid> </Window>
XAML eine Page:
<Page x:Class="WpfApp1CS.Window29Page1" 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:WpfApp1CS" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Title="Window29Page1"> <StackPanel> <Label Content="Page 1"/> <Button Content="Page 2" Command="{Binding Cmd}" CommandParameter="Page 2"/> </StackPanel> </Page>
Und dazu der ViewModel:
using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace WpfApp1CS { public class Window29VM:INotifyPropertyChanged { public Page ActualPage { get; set; } public ICommand Cmd { get { return new RelayCommand(CmdExec); } } private void CmdExec(object obj) { switch (obj.ToString()) { case "Page 1": ActualPage = new Window29Page1(); break; case "Page 2": ActualPage = new Window29Page2(); break; } ActualPage.DataContext = this; OnPropertyChanged(nameof(ActualPage)); } #region OnPropertyChanged public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); #endregion } }
--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks- Bearbeitet Peter Fleischer Sonntag, 21. Januar 2018 10:22
- Als Antwort vorgeschlagen Ivan DragovMicrosoft contingent staff, Moderator Donnerstag, 25. Januar 2018 07:59
- Als Antwort markiert Ivan DragovMicrosoft contingent staff, Moderator Freitag, 2. Februar 2018 06:20
-
Hallo,
vielen Dank für die super schnelle Antwort. Leider hat es bei mir funktioniert.
Ich bekomme zwar keine Fehler, aber es wird auch nichts angezeigt.
Was ich bei meiner ersten Frage verwechselt habe ist das, dass Frame nicht in eimem Window ist sondern in einer Page. Die Pages 1-9 sind mit den Buttons auf der Page mit dem Frame zu öffnen (über NavigateService.Navigate) das Problem ist die Page 10 welche über ein Button angezigt werden soll, der sich in der Page 9 befindet.
Hab es folgendermaßen versucht:
<Page x:Class="Test1.Einrichten" 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:Test1" mc:Ignorable="d" Title="Einrichten" Height="528" Width="1013"> <Grid> <StackPanel Width="145" HorizontalAlignment="Left" Margin="10,0,0,50"> <Button x:Name="Einrichten_Start" Command="{Binding Cmd}" CommandParameter="Page_1" Content="Einrichten Start" Margin="0,30,10,0" Height="50" BorderBrush="#FFCFCDCD" Foreground="Black" BorderThickness="0" Click="Einrichten_Start_Click"> <Button.Effect> <DropShadowEffect/> </Button.Effect> <Button.Background> <LinearGradientBrush EndPoint="0,0" StartPoint="0,0"> <GradientStop Color="#FFD6D6D6" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> <Button x:Name="Setzblech_Zuführung" Command="{Binding Cmd}" CommandParameter="Page_2" Content="Zuführung Setzblech" Margin="10,20,20,0" Height="40" BorderBrush="#FFCFCDCD" Foreground="Black" BorderThickness="0" Click="Setzblech_Zuführung_Click"> <Button.Effect> <DropShadowEffect/> </Button.Effect> <Button.Background> <LinearGradientBrush EndPoint="0,0" StartPoint="0,0"> <GradientStop Color="#FFF0EDED" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> <Button x:Name="Blister_Abführung" Command="{Binding Cmd}" CommandParameter="Page_3" Content="Blister Abführung" Margin="10,15,20,0" Height="40" BorderBrush="#FFCFCDCD" Foreground="Black" BorderThickness="0" Click="Blister_Abführung_Click"> <Button.Effect> <DropShadowEffect/> </Button.Effect> <Button.Background> <LinearGradientBrush EndPoint="0,0" StartPoint="0,0"> <GradientStop Color="#FFF0EDED" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> <Button x:Name="Messsystem" Command="{Binding Cmd}" CommandParameter="Page_4" Content="Messsystem" Margin="10,15,20,0" Height="40" BorderBrush="#FFCFCDCD" Foreground="Black" BorderThickness="0" Click="Messsystem_Click"> <Button.Effect> <DropShadowEffect/> </Button.Effect> <Button.Background> <LinearGradientBrush EndPoint="0,0" StartPoint="0,0"> <GradientStop Color="#FFF0EDED" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> <Button x:Name="Messtaster" Command="{Binding Cmd}" CommandParameter="Page_5" Content="Messtaster" Visibility="Collapsed" Margin="16,10,28.6,0" Height="29" BorderBrush="#FFCFCDCD" Foreground="Black" BorderThickness="0" Click="Messtaster_Click"> <Button.Effect> <DropShadowEffect/> </Button.Effect> <Button.Background> <LinearGradientBrush EndPoint="0,0" StartPoint="0,0"> <GradientStop Color="#FFF0EDED" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> <Button x:Name="Kalibrieren" Command="{Binding Cmd}" CommandParameter="Page_6" Content="Kalibrieren" Visibility="Collapsed" Margin="26,10,38.6,0" Height="29" BorderBrush="#FFCFCDCD" Foreground="Black" BorderThickness="0" Click="Kalibrieren_Click"> <Button.Effect> <DropShadowEffect/> </Button.Effect> <Button.Background> <LinearGradientBrush EndPoint="0,0" StartPoint="0,0"> <GradientStop Color="#FFF0EDED" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> <Button x:Name="Schwenkeinheit" Command="{Binding Cmd}" CommandParameter="Page_7" Content="Schwenkeinheit" Margin="10,15,20,0" Height="40" BorderBrush="#FFCFCDCD" Foreground="Black" BorderThickness="0" Click="Schwenkeinheit_Click"> <Button.Effect> <DropShadowEffect/> </Button.Effect> <Button.Background> <LinearGradientBrush EndPoint="0,0" StartPoint="0,0"> <GradientStop Color="#FFF0EDED" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> <Button x:Name="Roboter" Command="{Binding Cmd}" CommandParameter="Page_8" Content="Roboter" Margin="10,15,20,0" Height="40" BorderBrush="#FFCFCDCD" Foreground="Black" BorderThickness="0" Click="Roboter_Click"> <Button.Effect> <DropShadowEffect/> </Button.Effect> <Button.Background> <LinearGradientBrush EndPoint="0,0" StartPoint="0,0"> <GradientStop Color="#FFF0EDED" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> </StackPanel> <StackPanel Margin="10,478,858,0"> <Button x:Name="Service" Command="{Binding Cmd}" CommandParameter="Page_9" Content="Service" Margin="10,0,20,0" Height="40" BorderBrush="#FFCFCDCD" Foreground="Black" BorderThickness="0" Click="Service_Click"> <Button.Effect> <DropShadowEffect/> </Button.Effect> <Button.Background> <LinearGradientBrush EndPoint="0,0" StartPoint="0,0"> <GradientStop Color="#FFF0EDED" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> </StackPanel> <Frame Margin="155,0,0,0" Content="{Binding ActualPage}"/> </Grid> </Page>
using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace Test1 { public class Frame_1 : INotifyPropertyChanged { public Page ActualPage { get; set; } public ICommand Cmd { get { return new RelayCommand(CmdExec); } } private void CmdExec(object obj) { switch (obj.ToString()) { case "Page_1": ActualPage = new Einrichten_Start(); break; case "Page_2": ActualPage = new Setzblech_Zufuehrung(); break; case "Page_3": ActualPage = new Blister_Abfuehrung(); break; case "Page_4": ActualPage = new Messsystem(); break; case "Page_5": ActualPage = new Messtaster(); break; case "Page_6": ActualPage = new Kalibrieren(); break; case "Page_7": ActualPage = new Schwenkeinheit(); break; case "Page_8": ActualPage = new Roboter(); break; case "Page_9": ActualPage = new Login_Service(); break; case "Page_10": ActualPage = new Service(); break; } ActualPage.DataContext = this; OnPropertyChanged(nameof(ActualPage)); } #region OnPropertyChanged public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); #endregion } /// <summary> /// Interaktionslogik für Einrichten.xaml /// </summary> public partial class Einrichten : Page { public Einrichten() { InitializeComponent();
Noch irgendwelche Ideen?
-
... das Problem ist die Page 10 welche über ein Button angezigt werden soll, der sich in der Page 9 befindet.
...
Noch irgendwelche Ideen?
Aber genau das habe ich in meinem Beispiel gezeigt - Anzeige einer Page mit Button-Klick auf einer anderen Page (und auch vom Container mit dem Frame).
Wo ist denn Dein Problem?
--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks -
Hi,
aus Deinem Codeauszug kann ich nicht erkennen, ob Du alles so gemacht hast, wie ich es in meinem Beispiel gemacht habe. Unklar ist, wie Du den DataContext in der Einrichten-Seite gesetzt hast. Wenn es Bindungs-Probleme gibt, dann sollten diese auch im Ausgabe-Fenster beim Debugging ausgewiesen sein. Warum das bei Dir nicht so ist, kann ich aus der Ferne nicht erkennen.--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks