WInUI 3.0 Desktop - Crash on exception when try to navigate - c#

I want to change frame, but I get this exception:
Navigation:
Frame rootFrame = new Frame();
rootFrame.Navigate(typeof(ScoreWindow), null, new EntranceNavigationTransitionInfo());
Exception appears on constructor:
public ScoreWindow()
{
this.InitializeComponent();
results = new List<Result>();
playerList = new();
LoadData();
var _resultsView = ConvertToView();
sfDataGrid.ItemsSource = _resultsView;
}
Thanks for answers in advance and happy holidays!
P.S. Thanks to Raymond, I detected this message:
WinUI: Error creating second Desktop Window on the current process. No more than one Desktop Window is allowed per process.
There is another question: how to change current frame to other? I mean, I have login view, user logged in successfully and want to see data/other things.

After a little break, I understood what I did wrong. There is a way how to navigate between pages.
Rule #1: In WinUI, you have only one active window, and it's MainWindow. Always. If you want to change layout, you have to use Frames.
In MainWindow.xaml, you write this:
<Grid>
<Frame x:Name="mainFrame"/>
</Grid>
Element "Frame" give ability to navigate between pages.
Then switch to MainWindow.xaml.cs and in constructor have to be something like this:
public MainWindow()
{
InitializeComponent();
mainFrame.Navigate(typeof(NameOfYourPage));
}
It will immediately activate your page.
Then, if you want to navigate from page to page, write in control of page this:
Frame.Navigate(typeof(NameOfYourPage), null, new EntranceNavigationTransitionInfo());
The third parameter is animation, but I didn't notice changes.
More information you can find here:
Tutorial about navigation
Microsoft documentation

Related

How do I show a second page that I have created in XAML - UWP C#

I have made a program in WPF previously and am trying to transcirpt it into UWP. However I have come across a barrier.
In WPF you can easily create a new instance of a window and .Show that window
For example:
public static SecondGUI_Window secondGUI = new SecondGUI_Window();
secondGUI.Show();
However in UWP I am still confused as how to create a new window. I have tried doing it the same way as in WPF however it doesn't seem to work. I have also viewed and tried a couple of other answers from other stack overflow's
Second Window - XAML page (UWP app)
To no avail have I been able to get it working yet.
The main reason I want to have the second screen is so that I can display data on another screen.
For example the second window can be moved to another screen if the user has two screens.
I would like to keep as much of the usability/flexibility from WPF instancing as possible. For example being able to access the public variables in the window.
When I try and use the code from the example above it gives me an 'await' error.
Image showing error from visual studio
If you need any extra information please ask and I will try my best to provide any information requested.
Any and every help is greatly appreciated.
From the link provided by quaabaam I have managed to get it working.
From the code in the link I used in my question and some help from you guys I've now managed to have a second window running at the same time.
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
CoreApplicationView newView = CoreApplication.CreateNewView();
int newViewId = 0;
await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Frame frame = new Frame();
frame.Navigate(typeof(DisplayWindow), null);
Window.Current.Content = frame;
Window.Current.Activate();
newViewId = ApplicationView.GetForCurrentView().Id;
});
bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
}
Making sure I had the async in the method call, the program now opens a second window.
Now I need to make sure I can get the second window working how I want it to without any issues...

How to go back to main window from page in wpf?

On a C# application that I am working on, I have a frame on my main window.
<Frame x:Name="frame" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" NavigationUIVisibility="Hidden"/>
I click a button on my main window, and then I use the frame that I created to navigate to a page using the code below.
//Create a new object for the page
CameraPage camera = new CameraPage();
//Navigate to the new page
frame.NavigationService.Navigate(camera);
What I would like to do is if I click a button on the camera page that is contained within the frame, then it only exits the page while still keeping the main window intact.
I have tried something like this.
NavigationService.GoBack();
But then I get an error:
System.InvalidOperationException: 'Cannot navigate because there is no entry in the Back stack of the journal.'
I believe this error is happening because the navigation stack I used to go the page is apart of the main window code and not the page that I navigated to.
So my question really is, how do I close a page contained within a frame with a button contained within the page, without closing the entire application?
If you want to end up with an empty Frame again, all you have to do is clear the Frame's contents. According to this answer, you can do so like this:
frame.Content = null;
That will get you back to how things started, now you just to trigger it. For that, I'll refer you to the question WPF Frame and Page Get event. The answer there shows you how to use DelegateCommand (a.k.a. RelayCommand) to accomplish this. This is the way I would go, because it keeps the Page nice and separate from whatever Window is hosting it.
Technically, you could also pass your Page a reference to frame when you initialize it, then have it set frame.Content = null; that way. But that's a sort of "quick and dirty" approach, not really a best practice.

How to best implement a log in page with Caliburn.Micro MVVM

I am new to using caliburn.micro and currently learning MVVM.
I am using the windows template studio to create my UWP app, and it works great! But unfortunately, I am not familiar with MVVM and still learning UWP.
I get how the navigation works etc and how the shellpage is loaded. However, I want to prompt the user to log in upon opening the app (i.e. a login in page will start with no navigation sidebar).
I also want to make sure I'm following best practices...
I have tried substituting the MainViewModel with LoginViewModel which I get works, however, I don't want to create the navigation pane. I get that this is triggered by the "new Lazy(CreateShell)". I'm just not sure if I want to remove this from the activation service and call a method upon login?
Below is the default code supplied by the windows template studio which triggers on activation of the app if I understand correctly.
private ActivationService CreateActivationService()
{
return new ActivationService(_container, typeof(ViewModels.LoginViewModel), new Lazy<UIElement>(CreateShell));
}
private UIElement CreateShell()
{
var shellPage = new Views.ShellPage();
_container.RegisterInstance(typeof(IConnectedAnimationService), nameof(IConnectedAnimationService), new ConnectedAnimationService(shellPage.GetFrame()));
return shellPage;
}
I just need to be pointed in the right direction or lead to a video/tutorial as I'm struggling!!! any help much appreciated.
If you want to show login page,you can remove the ShellPage.It is a navigation view.
in App.xaml.cs
private ActivationService CreateActivationService()
{​
return new ActivationService(this, typeof(LoginPage));​
}​
​
private UIElement CreateShell()​
{​
return new Views.ShellPage();​
}
When login successfully,if you want to show the navigation view,you can set the ShellPage to the content of current window.
Window.Current.Content = new Views.ShellPage();

Prism Navigation Not Working In New Window

Edit: Please see my comment below - the code itself seems to be correct (at least the Prism region code) but navigation in the new window instance is still not working.
To start off with, here is the issue I'm having...
I have a main window with a menu bar that switches views in the main window to take the user to different screens. This is all working great.
So I thought today that I would add a 'first time user' screen to handle all the initial setup for the application. This is a new window that will pop up if certain first time properties haven't been set and welcome the new user, get the initial setup complete, etc. I wanted to have navigation on this new window in a new region (just next and back buttons that take the user through the setup).
I thought this would be easy but after 3 hours of floundering and searching the darkest corners of the web I am still very confused - I also looked at Brian Lagunas' Pluralsight videos on MVVM but nothing I have tried to apply is working to setup navigation on the new window.
The content region for the main window is named "ContentRegion" and the content region for the new window is named "SetupRegion".
All views are registered in the bootstrapper like so:
// All views must be registered.
Container.RegisterTypeForNavigation<Home>( "Home" );
Container.RegisterTypeForNavigation<Index>( "Index" );
Container.RegisterTypeForNavigation<Settings>( "Settings" );
Container.RegisterTypeForNavigation<FirstTimeSetupWelcomeScreen>( "WelcomeScreen" );
Container.RegisterTypeForNavigation<FirstTimeSetupScreen2>( "FirstTimeSetupScreen2" );
Here is how the new window is being instantiated currently, from the main window:
public MainWindowViewModel(IRegionManager _regionManager, EventAggregator _eventAggregator)
{
eventAggregator = _eventAggregator;
regionManager = _regionManager;
NavigateCommand = new DelegateCommand<string>(Navigate);
// Set the default view to the home screen
regionManager.RegisterViewWithRegion("ContentRegion", typeof(FirstTimeSetupWelcomeScreen));
// Check to see if program is in first time run or not
if ((ConfigurationManager.GetSection("SaveLocationsGroup/Locations") as IndexLocationsSection).SaveLocation.Location == "")
{
var firstTimeWindow = new FirstTime();
firstTimeWindow.Show();
// Set the default view to the welcome screen on new window
regionManager.RegisterViewWithRegion("SetupRegion", typeof(FirstTimeSetupWelcomeScreen));
}
}
In the XAML for the new window, the content control is setup like this:
<Grid>
<ContentControl prism:RegionManager.RegionName="SetupRegion" />
</Grid>
I have tested by replacing the code in the Navigate command on the main window and having it to navigate to the new user controls, showing them in the main window and that works.
However, in the new window they are not and I can't seem to figure out why. I have also tested to see if the button in the first/default user control view model is firing correctly and it is - for reference, here is that Navigate command code:
private void Navigate(string uri)
{
// WriteLine command to test the button firing
Console.WriteLine(uri);
regionManager.RequestNavigate("SetupRegion", uri);
}
Lastly I've placed the first view inside the main window and it seems to fire correctly, changing the content in the main window - I just can't get it to work or anything to work on the new window at all no matter how I try it. I'm assuming that there is something that I don't know that has to do with either navigation on new instances of windows (aside from the main window) or having to do with containers and new windows but I haven't been able to figure out what. Thank you guys for all of your assistance as always.
It turn out Brian Lagunas has a course on multiple shells I should hopefully be able to use to accomplish what I need. I will attempt to use it.

Override BackKeyPress in a classlibrary, is that possible on WP8?

I pass a PhoneApplicationPage instance to a classlibrary, and popup an usercontrol in this classlibrary, when I press back button, the whole application exit. Yesterday I sovled the problem in an application, but I cannot use the method in this classlibrary case.
I tried to subscribe to the event(BackKeyPress), but VS2012 says "parent_BackKeyPress" "System.EventHandler" override and delegate cannot match. I checked, they match.
PhoneApplicationPage mContext=...;
mContext.BackKeyPress += new EventHandler(parent_BackKeyPress);
void parent_BackKeyPress(CancelEventArgs e)
{
ppChangePIN.IsOpen = false;
Application.Current.RootVisual.Visibility = Visibility.Visible;
}
anything incorrect here? plus, can I use navigationservice in classlibrary? I did this before to navigate to a page created in the classlibrary like below, well it ends up crashing. Some say can't use pages in classlibrary, instead we should use Popup(usercontrol).
mContext.NavigationService.Navigate(new Uri("/ChangePINPage.xaml", UriKind.Relative));
I have successfully done just that:
// or some other method of accessing the current page
// - but via Application, to which you have access also in class library
var currentPage = (PhoneApplicationPage)((PhoneApplicationFrame)Application.Current.RootVisual).Content;
currentPage.BackKeyPress += (sender, args) =>
{
// Display dialog or something, and when you decide not to perform back navigation:
args.Cancel = true;
};
Of course you have to make sure that this code is executed if and only if the CurrentPage is the main page.
I also use Pages in class library. You can use NavigationService in class library: you can get it for example from current page obtained as above (currentPage.NavigationService). Or you could use the Navigate method of PhoneApplicationFrame:
((PhoneApplicationFrame)Application.Current.RootVisual)
.Navigate(
new Uri(
"/ClassLibraryName;component/SamplePage.xaml",
UriKind.Relative));
As the short Uris like "/SamplePage.xaml" will work in Application Project, to navigate to page in class library you have to give full location: "/ClassLibraryName;component/SamplePage.xaml".
But note, that if the application chooses to display message box to stop from exiting, it will not pass certification, as (from Technical certification requirements for Windows Phone):
5.2.4.2 – Back button: first screen
Pressing the Back button from the first screen of an app must close the app.

Categories