-1

once to explain, I open a xaml page via "frame.content" and in this page I have opened, I want to open another one but on the frame where the second page is running. but i can't open the page,

nothing happens. not even an expection.

So here what I have written:


This is the class from the page that is open

private void bttn_start(object sender, RoutedEventArgs e)
{
   MainWindow mw = new MainWindow();
   mw.JoinNextPage();
}

This is the MainWindow class where the frame is.

public partial class MainWindow : Window
{ 
   public void JoinNextPage() => pageMirror.Content = new page_finish();
}

Schecher_1
  • 343
  • 4
  • 12
  • The problem is not clear. – BionicCode Oct 15 '21 at 13:26
  • @BionicCode Wie meinen sie das? Ich kann halt nicht extern auf einem Frame zugreifen. Also den "content" ändern. – Schecher_1 Oct 15 '21 at 13:34
  • It's not clear from where you want to show the page. Does JoinNextPage fail? – BionicCode Oct 15 '21 at 13:51
  • @BionicCode Well, I have created a programme where you can navigate through pages. And for this I took a "" and called it "pageMirror". And on this frame the XAML pages will be displayed. Which also works, but when I want to call another page from the page I called, nothing happens. It goes to the function but nothing is executed.But when I do this internally everything works but externally my "request" goes nowhere. And my object is always defined as "null" when I do it externally. – Schecher_1 Oct 15 '21 at 14:00
  • I can display all pages (as long as I am in the class where the " is"), but as soon as I want to access it externally, my object is always defined as "null". – Schecher_1 Oct 15 '21 at 14:04
  • Your posted code does not show how you were trying to navigate pages from a currently displayed Page. Therefore I can't tell what went wrong. Generally you can use the Page's NavigationService property to navigate to a different Page within the current Page's owning Frame. – BionicCode Oct 15 '21 at 14:26
  • So I'll describe it again, as an example we now have page A, B and C. Page A is the main page, I have a frame with the name "pageMirror" where I can call another page with "pageMirror.Content = new {pageName}". If I press a button in page A that executes "pageMirror.Content = new page_main();", everything works and page B is displayed. But now on this new page there is also a button that executes "mw.JoinNextPage();" so "pageMirror.Content = new page_finish();" which should open page C. But it doesn't work. But this does not work. The function is called but the command set is not executed. – Schecher_1 Oct 15 '21 at 14:38
  • @BionicCode So, I'll try to summarise. When I execute the command in the class. It works, but if I want to call this command from another class, nothing happens. Have I created a wrong object reference? – Schecher_1 Oct 15 '21 at 14:42
  • Have you tried my suggestion to use the Page.NavigationService of the currently active page (from inside the page)? – BionicCode Oct 15 '21 at 14:55
  • You must call NavigationService.Navigate() from within the Page.. – BionicCode Oct 15 '21 at 14:56
  • @BionicCode Yes, I have already done it more times and everywhere. It doesn't work externally, but internally it always works. Strange, as if I have done my object reference wrong. – Schecher_1 Oct 15 '21 at 15:06
  • The Page must be hosted by the Frame you want to navigate in. The NavigationService maps to the current Frame. Do you have two or more frames? Reviewing your code, you are creating a new Window instance evertime you are clicking the Button. This means you have multiple pageMirror Frames - one per each bttn_start invocation. I doubt that this is what you want. If you want to show all Pages in the same Frame, then stop creating a new MainWindow on each call. You probably want a single instance of pageMirror. – BionicCode Oct 15 '21 at 15:21
  • You should be fine if you use the NavigationService and remove the mw.JoinNextPage(); from your button handlers. You may have to call it once, at the first click of Page A (I don't now your logic). – BionicCode Oct 15 '21 at 15:24
  • So replace the event handler's mw.JoinNextPage() with NavigationService.Navigate. Or handle the button clickk event directly in the MainWindow. This is cleaner as in your scenario the navigation logic is implemented in your MainWindow. – BionicCode Oct 15 '21 at 15:29
  • @BionicCode Finally I know what happens now, I create a new "MainWindow" and don't use the current one.... Because when I do "mw.show();" I see that the window has opened exactly the page. Now my question is, do you know how I can make an object white without creating a new "MainWindow" but using the current one? – Schecher_1 Oct 15 '21 at 15:30
  • You should drop the Frame and use a ContentControl instead. The Frame has a bad performance. If you don't need to show web content don't use it. https://stackoverflow.com/a/61323201/3141792 – BionicCode Oct 15 '21 at 15:31
  • :) Would you mind to elaborate on *"make an object white without creating a new "MainWindow""*? Do you mean to remove/replace the content of the WIndow? – BionicCode Oct 15 '21 at 15:33
  • Using the pattern provided by the above link will make page navigation easier I guess. It's perfect for MVVM. You can keep the navigation logic in the view model where most of your commands are executed. – BionicCode Oct 15 '21 at 15:35
  • "mean to remove/replace the content of the WIndow?" Yeah, i mean this. – Schecher_1 Oct 15 '21 at 15:38
  • Do you use the Window to host the page content? Generally you can use DataTemplate to change the content of a Window dynamically. Window is a ContentControl. That means you can always set the Content to null: window.Content = null; – BionicCode Oct 15 '21 at 15:40
  • @BionicCode actually what "Dark Templar" wrote works. It does what I meant. sorry if I wrote my question and answers too unclear. May be because it is my first question here. – Schecher_1 Oct 15 '21 at 15:44
  • I really suggest to not do it that way. Let me show you a better way. – BionicCode Oct 15 '21 at 15:55
  • @BionicCode With pleasure, if it is cleaner. But otherwise I would have "my" alternative – Schecher_1 Oct 15 '21 at 15:59
  • You decide. With the below approach you don't need any navigation logic in your pages. You only have the existing logic in your MainWindow. – BionicCode Oct 15 '21 at 16:01

2 Answers2

0

You should use RoutedCommand to trigger the Frame navigation instead of the static MainWindow reference.

This removes the complete navigation logic (button event handlers) from your pages.

MainWindow.xaml.cs

public partial class MainWindow : Window
{
  public static RoutedCommand NextPageCommand { get; } = new RoutedCommand("NextPageCommand", typeof(MainWindow));

  public MainWindow()
  {
    InitializeComponent();

    CommandBindings.Add(
      new CommandBinding(NextPageCommand, ExecuteNextPageCommand, CanExecuteNextPageCommand));      
   }

  private void CanExecuteNextPageCommand(object sender, CanExecuteRoutedEventArgs e)
  {
    e.CanExecute = true;
  }

  private void ExecuteNextPageCommand(object sender, ExecutedRoutedEventArgs e)
  {
    // Logic to select the next Frame content
    JoinNextPage();
  }
}

MainWindow.xaml

<Window>
  <Frame>
   <Frame.Content>
     <Page>
       <Button Command="{x:Static local:MainWindow.NextPageCommand}" 
               Content="Next Page" />
      </Page>
    </Frame.Content>
  </Frame>
</Window>
BionicCode
  • 1
  • 4
  • 28
  • 44
  • It looks interesting but i get "Error XDG0012 The element "NextPageCommand" was not detected, or the element cannot be accessed." – Schecher_1 Oct 15 '21 at 16:20
  • Have you defined the command static? The above "example" does not include the namespace definitions in XAML. For example you need to define `xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"` in order to use `x:Static`. – BionicCode Oct 15 '21 at 17:05
  • You're not using NavigationService, you just use a command to call his method. https://learn.microsoft.com/en-us/dotnet/api/system.windows.navigation.navigationservice?view=windowsdesktop-5.0 – Dark Templar Oct 15 '21 at 22:25
  • @DarkTemplar Yes, very true. I chose to use a RoutedCommand in order to remove the navigation logic completely from the page (which makes the Button.Click handler obsolete - in addition to removing the reference to the MainWindow). – BionicCode Oct 15 '21 at 22:30
  • @BionicCode Thank you, this is actually the best idea and it is much cleaner. Have a nice day – Schecher_1 Oct 16 '21 at 11:28
-1

Try this:

private void bttn_start(object sender, RoutedEventArgs e)
{
   MainWindow mw = (MainWindow)Application.Current.MainWindow;
   mw.JoinNextPage();
}
Dark Templar
  • 1,130
  • 8
  • 10
  • It would be better to use the Page's NavigationService instead of depending on a method in the MainWindow (or external Window in general). That'S what the service is for. It helps to decouple the Page from the hosting view. – BionicCode Oct 15 '21 at 15:26