Navigation between pages in WPF? - c#

I have my WPF application and my button is on a WINDOW that I added and I want the button to open a PAGE when I click it.
NavigationService nav = NavigationService.GetNavigationService(this);
nav.Navigate(new Uri("xamlFeedbackPage.xaml", UriKind.RelativeOrAbsolute));
I have tried that code that was online and my application crashes when I click the button.
Any help?

Take a look at this post and this MSDN article. They contain explanation about what kind of Types are suitable for navigation (pages) and in which container to host them (basically a Frame). Then you should have some succes.
EDIT
Take a look at this extensive example and things will become clear.

public PageFunction1()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
NavigationService nav = NavigationService.GetNavigationService(this);
nav.Navigate(new Uri("page2.xaml",UriKind.RelativeOrAbsolute));
}

No need of call anything in the code.Since it can be done with xaml itself.
App.xaml
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Page1.xaml">
</Application>
Page1
<Page x:Class="WpfApplication1.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1">
<StackPanel>
<TextBlock>
Go to <Hyperlink NavigateUri="Page2.xaml"> Page 2 </Hyperlink>
</TextBlock>
</StackPanel>
</Page>
Navigate sample
Page 2
<Page x:Class="WpfApplication1.Page2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page2">
<StackPanel>
<TextBlock Margin="10">Welcome to Page2.</TextBlock>
<TextBlock Margin="10">
Go back to <Hyperlink NavigateUri="Page1.xaml"> Page 1 </Hyperlink>
</TextBlock>
</StackPanel>
</Page>

Related

RoutedCommand in UserControl is not working as expected

I am trying to use RoutedCommands in my UserControls, following the example in this article:
https://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/
I defined the RoutedCommand and CommandBindings in the UserControl instead of in the article's example. I am trying to use it in my MainWindow, so that when the Button is clicked, the Command in the UserControl is executed. However, the Button is disabled and the Foo_CanExecute() method is never executed.
<UserControl x:Class="RoutedCommandTest.ViewControl"
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:RoutedCommandTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.CommandBindings>
<CommandBinding
Command="{x:Static local:ViewControl.Foo}"
PreviewCanExecute="Foo_CanExecute"
PreviewExecuted="Foo_Executed"
/>
</UserControl.CommandBindings>
<Grid>
</Grid>
</UserControl>
Here is the code for ViewControl.xaml.cs:
public static readonly RoutedCommand Foo = new RoutedCommand();
void Foo_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
void Foo_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("The Window is Fooing...");
}
public ViewControl()
{
InitializeComponent();
}
And here is the code for MainWindow.xaml:
<Window x:Class="RoutedCommandTest.MainWindow"
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:RoutedCommandTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:ViewControl/>
<Button Content="Foo" Margin="0 5" Command="{x:Static local:ViewControl.Foo}"/>
</Grid>
</Window>
I would like to know how to fix the issue so that the Button is enabled and the Foo_CanExecute() method is executed when the Button is clicked.
Your command is in a usercontrol, whilst the button is in mainwindow.
Which presumably contains your usercontrol.
Like bubbling and routing events ( which are used to drive them ).
Executed looks for the command bubbling UP the visual tree to the binding.
PreviewExecuted looks for the command tunnelling DOWN the visual tree to the binding.
Since your button is in the parent of the usercontrol I'm not sure whether either bubbling or tunnelling will work.
But tunnelling would be PreviewExecuted And PreviewCanExecute.
https://learn.microsoft.com/en-us/dotnet/api/system.windows.input.commandbinding.previewexecuted?view=netframework-4.8
https://learn.microsoft.com/en-us/dotnet/api/system.windows.input.commandbinding.previewcanexecute?view=netframework-4.8
Routedcommands can be pretty tricky to get right.
One thing you sometimes have to do is to bind commandtarget to tell it where to go look.
eg:
<Grid>
<local:UserControl1 x:Name="UC1" Height="60" Width="100"/>
<Button Content="Foo" TextElement.FontSize="30" Command="{x:Static local:UserControl1.Foo}"
CommandTarget="{Binding ElementName=UC1}"
/>
</Grid>
Works for me.
I have rarely found them useful - this is one of the aspects makes them way less useful than you might at first imagine.
EDIT:
It's perhaps worth mentioning the other thing makes these unattractive compared to a regular icommand. You need to either use a static which means it's only suitable for very generic commands OR you need event handlers which will be in code behind.
On the other hand.
If you're writing something has to work generically with whatever has focus. Like say a text editor with multiple textboxes and you're doing text manipulation. A routed command might be suitable. I have never encountered such a requirement in apps I've worked on though.

WPF - Prism 7.1 - Navigation - Mastering Tab Control - Modal/Dialog Window

I am using Prism 7.1 navigation framework (WPF) to get a dialog window to pop up using the configuration below. This is successful. However, I want this popup to have tabs that I can navigate back and forth among. When I click the button on the popup box in an attempt to display ViewA inside of it, nothing happens. By setting a breakpoint, I see that the navigation path is hit, and is displaying the correct view name. Refer to PopUpWindow.cs. However when it goes to resolve the view, the view does not display. Even worse, no error is thrown! I am confused as to why this is occurring.
Assuming my namespaces are correct, what am I doing wrong?
PrismApplication.cs
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<ViewA>();
}
//Have tried register type, register type for navigation, etc etc.
MainWindowViewModel.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
Height="350" Width="525">
<i:Interaction.Triggers>
<prism:InteractionRequestTrigger SourceObject="{Binding NotificationRequest}">
<prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True" />
</prism:InteractionRequestTrigger>
</i:Interaction.Triggers>
<StackPanel>
<Button Margin="5" Content="Raise Default Notification" Command="{Binding NotificationCommand}" />
</StackPanel>
MainWindowViewModel.cs
public MainWindowViewModel
{
public InteractionRequest<INotification> NotificationRequest { get; set; }
public DelegateCommand NotificationCommand { get; set; }
public MainWindowViewModel()
{
NotificationRequest = new InteractionRequest<INotification>();
NotificationCommand = new DelegateCommand(RaiseNotification);
}
void RaiseNotification()
{
NotificationRequest.Raise(new PopupWindow());
}
}
PopUpWindow.xaml
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
Height="350" Width="525">
<DockPanel LastChildFill="True">
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="5" >
<Button Command="{Binding NavigateCommand}" CommandParameter="ViewA" Margin="5">Navigate to View A</Button>
</StackPanel>
<ContentControl prism:RegionManager.RegionName="ContentRegion" Margin="5" />
</DockPanel>
</UserControl>
PopUpWindow.cs
public class PopupWindowViewModel
{
private readonly IRegionManager _regionManager;
public DelegateCommand<string> NavigateCommand { get; private set; }
public PopupWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
NavigateCommand = new DelegateCommand<string>(Navigate);
}
private void Navigate(string navigatePath)
{
if (navigatePath != null)
_regionManager.RequestNavigate("ContentRegion", navigatePath);
//During debugging, this correctly shows navigatePath as "ViewA"
}
}
ViewA.xaml
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True">
<Grid>
<TextBlock Text="ViewA" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</UserControl>
Maybe it's just not finding your view.
Isn't the second parameter supposed to be a url rather than a string?
From here:
https://prismlibrary.github.io/docs/wpf/Navigation.html
IRegionManager regionManager = ...;
regionManager.RequestNavigate("MainRegion",
new Uri("InboxView", UriKind.Relative));
Check where your view is and what the path should be.
I think you could prove that using something like:
var testinstance = System.Windows.Application.LoadComponent(testUrl);
https://learn.microsoft.com/en-us/dotnet/api/system.windows.application.loadcomponent?view=netframework-4.7.2
And if you're using MEF I think you also need to mark the View with the Export attribute.
Hopefully your problem is just you forgot about a folder or some such.
If not then it could be related to regionmanager not getting a reference to your region.
Regions that aren't in the visual tree are ignored by the region manager. You define ContentRegion within the PopUpWindow (which is lazily created), so it is not there and the navigation request for the unknown region is just ignored.
As detailled here and there, in this case, you have to add the region manually in the constructor of the view containing it:
RegionManager.SetRegionName( theNameOfTheContentControlInsideThePopup, WellKnownRegionNames.DataFeedRegion );
RegionManager.SetRegionManager( theNameOfTheContentControlInsideThePopup, theRegionManagerInstanceFromUnity );
with a region manager from the ServiceLocator:
ServiceLocator.Current.GetInstance<IRegionManager>()
The InteractionRequest pattern is a bit quirky. You need to make sure that all views that should react on the request have the necessary InteractionRequestTrigger in the visual tree. Thus, the immediate fix to your problem is to copy your XAML from MainWindowView.xaml to ViewA.xaml:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
Height="350" Width="525">
<i:Interaction.Triggers>
<prism:InteractionRequestTrigger SourceObject="{Binding NotificationRequest}">
<prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True" />
</prism:InteractionRequestTrigger>
</i:Interaction.Triggers>
<!-- ... -->
</UserControl>
Then make sure to add the NotificationRequest in the viewmodel for ViewA. Please note that you may still encounter scenarios where the interaction request doesn't work. E.g. when adding triggers inside a data template. Though, as long as you put them on the UserControl level you should be fine.
One possible improvement to this (flawed) design is to create a behavior where you programmatically add these interaction triggers.

Navigation in Windows Universal Apps 10 Not Working (Taking me to a blank page)

and thank you. I'm using Visual Studio 2015 and trying to navigate between 2 pages, MainPage.xaml and Meds.xaml On MainPage.xaml I put this button to navigate to Meds.xaml with.
<Button x:Name="button_meds" Content="Meds" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="268,405,0,0" FontSize="18.667" Click="button_meds_Click"/>
In the MainPage.xaml.cs file, I simply did this
private void button_meds_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(Meds));
}
Meds.xaml has an image and background, but I omitted the logo and grid from the code below
<Page
x:Class="SQLMobileMoodSwing.Meds"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SQLMobileMoodSwing"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
</Page>
I'm not getting any errors, but when I click the button, it simply takes me to a white page. Not sure what I'm doing wrong, have looked for solutions but nothing seems to work.
Thank you!
I have created Meds.xaml as XAML View, not as Blank Page.
Then I deleted it and created again as a Blank Page and BOOM! It works

How to Navigate from One Page to Another in WPF

I have a MainWindow.XAML and CustomersView.XAML.
When I click the Customer Button on MainWindow , I want to navigate to CustomersView.XAML and palong with that need to pass few parameters.
I can use NavigationService but is only available with Pages and not Window.Hyperlink is not an option at this moment.
This might be fairly simple thing but not sure how can I implement this using MVVM and with out any third party control.
private void Navigate_Click(object sender, RoutedEventArgs e)//By Prince Jain
{
this.NavigationService.Navigate(new Uri("Page3.xaml", UriKind.Relative));
}
There are many options to navigate from one window to another in WPF. You can use a frame in your MainWindow and navigate all your pages right inside your Frame.
<Window
x:Class="NavigationSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<DockPanel>
<Frame x:Name="_mainFrame" />
</DockPanel>
</Window>
From code, you can tell the frame to navigate, like so:
_mainFrame.Navigate(new Page1());
Which just so happens to be a helpful shortcut to:
_mainFrame.NavigationService.Navigate(new Page1());
Or if you using any framework like PRISM, you are allowed to create a Shell where you can define regions and let your pages navigate to that.
Navigation Using the Prism Library 5.0 for WPF
Simple Way in XAML:
<Button HorizontalAlignment="Right" Name="continueButton" Width="75"
Margin="0,0,8,11" Height="23" VerticalAlignment="Bottom"
Click="continueButton_Click">
Navigate
</Button>
C#:
private void continueButton_Click(object sender, RoutedEventArgs e)
{
this.NavigationService.GoForward();
//or
this.NavigationService.Navigate("Second.xaml")
}
In MVVM XAML:
<Button Command="{x:Static Views:Commands.NavigateHelp}"
Content="Help"/>
In Views (We have a Commands.cs file that contains all of these):
public static RoutedCommand NavigateHelp = new RoutedCommand();
In the page constructor, you can connect the two:
CommandBindings.Add(new CommandBinding(Commands.NavigateHelp,
NavigateHelpExecute));
NavigateHelpExecute can be in the code behind (which is what we do), hook into a ViewModel event handler, or whatever. The beauty of this is that you can disable other navigation like so:
CommandBindings.Add(new CommandBinding(NavigationCommands.Refresh, null));

How can i link a canvas on a grid, to the mainwindow.xaml?

I have a canvas in a grid, i want to keep my canvas on that grid, because its the first window, that opens in my program.
In my MainWindow.xaml, i have a ContentPage, that always changes its content, the startup content is the authenticationPage. In this page i have a Canvas that shows my skeletal tracking, and is used for making a gesture. This gestureCanvas is on my authenticationPage. The code behind this gestureCanvas is on my MainWindow.xaml.cs.
I need to link the gestureCanvas with my MainWindow.xaml.cs, because the code is behind MainWindow, and it's going to be used there, because it's an Kinect application.
How to link these ?
partial class MainWindow
{
void LoadCircleGestureDetector()
{
using (Stream recordStream = File.Open(circleKBPath, FileMode.OpenOrCreate))
{
circleGestureRecognizer.TraceTo(gesturesCanvas, Colors.Red);
}
}
}
This is my authenticationPage
<UserControl
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:smartHome2011"
xmlns:MyUserControl="clr-namespace:MyUserControl;assembly=MyUserControl"
mc:Ignorable="d"
x:Class="smartHome2011.AuthenticationPage"
x:Name="UserControl"
d:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot">
<Grid x:Name="kinectGrid" HorizontalAlignment="Left">
<Viewbox Margin="204,220,430,220">
<Grid ClipToBounds="True" Margin="204,220,430,220">
**<Canvas x:Name="gesturesCanvas" />**
<Canvas x:Name="kinectCanvas"></Canvas>
</Grid>
</Viewbox>
</Grid>
</Grid>
at your code behind MainWindow you can try following
var gesturesCanvas = YourContentPage.FindName("gesturesCanvas") as Canvas;
if (gesturesCanvas != null) {
// do something
}
hope this helps

Categories

Resources