Shri
Shri

Reputation: 73

How to navigate to another user control by clicking a button in a usecontrol

I have a user control (UserLogin.xaml) in my MainWindow and I want to navigate to another user control (ShowPage.xaml) by clicking a button inside the UserLogin user control. And I want to do this in code.

This is my UserLogin UserControl.

<UserControl x:Class="bAV.UserLogin"
         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" 
         mc:Ignorable="d" 
          Height="{Binding SystemParameters.PrimaryScreenHeight}" 
         Width="{Binding SystemParameters.PrimaryScreenWidth}">
    <Grid>
        <Button Content="LogIn" Name="btnlogin" Click="btnlogin_Click" />
    </Grid>
</UserControl>

And when the button is clicked, I want to navigate to another UserControl ShowPage.xaml.

private void btnlogin_Click(object sender, RoutedEventArgs e)
{   
    Uri uri = new Uri("Showpage.xaml", UriKind.Relative);
    NavigationService ns = NavigationService.GetNavigationService(this);
    ns.Navigate(uri);
    //here I am getting object reference not set to an instance of an object       
}

This is MainWindow

<Window x:Class="bAV.MainWindow"
         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" 
         mc:Ignorable="d" xmlns:my="clr-namespace:bAV" WindowState="Maximized"> 
    <Grid>
        <my:UserLogin HorizontalAlignment="Center" VerticalAlignment="Center" />      
   </Grid>
</Window>

And the new UserControl I want to navigate to.

<UserControl x:Class="bAV.Showpage"
         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" 
         mc:Ignorable="d" 
         Height="{Binding SystemParameters.PrimaryScreenHeight}" 
         Width="{Binding SystemParameters.PrimaryScreenWidth}">
    <Grid>
    </Grid>
</UserControl>

Upvotes: 1

Views: 9209

Answers (2)

Kabir Costa
Kabir Costa

Reputation: 21

Translated by Google Translate, sorry :)

Describe below a simple solution:

  1. I created two UserControls: UserControl1.xaml and UserControl2.xaml
  2. Inside each UserControl I created a simple feature, only to differentiate them.
  3. Example: TextBox and TextBlock...
  4. In MainWindow I created the following:

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>
        <ListBox Grid.Column="0">
            <ListBoxItem Name="PrimeiraJanela" 
                         MouseUp="PrimeiraJanela_MouseUp">
              Primeira opção</ListBoxItem>
            <ListBoxItem Name="SegundaJanela" 
                         MouseUp="SegundaJanela_MouseUp">
              Segunda opção</ListBoxItem>
        </ListBox>
        <ContentControl x:Name="UserControls" Grid.Column="1"/>
    </Grid>

  1. The goal is that when you click the ListBox Item "PrimeiraJanela" the ContentControl load UserControl1, when you click the ListBoxItem "SegundaJanela" the ContentControl load UserControl2.
  2. Editing the Code-Behind, do the following:

    public partial class MainWindow : Window
    {
        UserControl1 user1 = new UserControl1();
        UserControl2 user2 = new UserControl2();

        public MainWindow()
        {
            InitializeComponent();
        }

        private void PrimeiraJanela_MouseUp(object sender, MouseButtonEventArgs e)
        {
            UserControls.Content = null;
            UserControls.Content = user1;
        }

        private void SegundaJanela_MouseUp(object sender, MouseButtonEventArgs e)
        {
            UserControls.Content = null;
            UserControls.Content = user2;
        }
    }

This is the simplest solution I know. (I am beginner in WPF)

Upvotes: 1

kennyzx
kennyzx

Reputation: 12993

NavigationService (your attempt)

WPF has two navigators: NavigationWindow and Frame. Only these navigators have NavigationService to navigate contents. So you first have to put UserLogin inside a Frame, or you will get null when you call NavigationService.GetNavigationService.

<Window x:Class="bAV.MainWindow"
     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" 
     mc:Ignorable="d" xmlns:my="clr-namespace:bAV" WindowState="Maximized"> 
    <Grid>
        <Frame Source="UserLogin.xaml" />
    </Grid>
</Window>

Another solution without using navigation service

Add both UserControls to MainWindow, first Showpage and then UserLogin, at first only UserLogin is visible and Showpage is hidden behind it.

<Window x:Class="bAV.MainWindow"
     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" 
     mc:Ignorable="d" xmlns:my="clr-namespace:bAV" WindowState="Maximized"> 
    <Grid>
        <my:Showpage />
        <my:UserLogin />      
    </Grid>
</Window>

When button is click, hide UserLogin so Showpage becomes visible.

private void btnlogin_Click(object sender, RoutedEventArgs e)
{
    this.Visibility = System.Windows.Visibility.Collapsed;
}

Upvotes: 5

Related Questions