user13812143
user13812143

Reputation:

Navigate to another tab item by a button click from the tab having multiple view models doesn't work

I have to navigate to another tab by a button click from the first tab in a WPF MVVM Application(c#). I am trying to achieve this by adding binding to Selected Index property in tab control.There are two different view models are used in the first tab.After adding binding to Selected Index property in tab control it loses the rest of view model's access and No data is present on the text boxes in the first tab. Also navigation is not working . how can I use tab navigation if the window has multiple view models. please see sample code.

XAML file

MainWindow.xaml

  <Grid>
    <TabControl SelectedIndex="{Binding SelectedTab,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                 DataContext="{Binding processVM}">
        <TabItem Header="Home">
            <Grid ShowGridLines="false" >
                <Grid.ColumnDefinitions >
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="50" />
                    <RowDefinition Height="50" />
                    <RowDefinition Height="50" />
                </Grid.RowDefinitions>
                <TextBox Name="txtCustomerName" 
                         Grid.Row="0" Grid.Column="1"
                         Text="{Binding CustomerName}"
                       DataContext="{Binding customerVM}"></TextBox>
                <TextBox Name="txtDepositAmount" 
                         Grid.Row="1" Grid.Column="1"
                         Text="{Binding DepositAmount}"
                       DataContext="{Binding customerVM}"></TextBox>
                <Button Content="Click"  Width="100" Height="50"
                        Grid.Row="2" 
                        DataContext="{Binding processVM}"
                        Command="{Binding ButtonCommand}"                             
                        />
            </Grid>

Code behind

MainWindow.xaml.cs

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel()
            {
                processVM = new ProcessViewModel(),
                customerVM = new CustomerViewModel()
            };
        }
    }

View Models

MainWindowViewModel.cs

  class MainWindowViewModel
    {
        public ProcessViewModel processVM { get; set; }
        public CustomerViewModel customerVM { get; set; }
    }

ProcessViewModel.cs

 public class ProcessViewModel: INotifyPropertyChanged
    {
        private string depositAmount;

        public string DepositAmount
        {
            get { return depositAmount; }
            set {
                depositAmount = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("DepositAmount"));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private ICommand m_ButtonCommand;
        public ICommand ButtonCommand
        {
            get
            {
                return m_ButtonCommand;
            }
            set
            {
                m_ButtonCommand = value;
            }
        }

        private int selectedTab;

     

        public int SelectedTab
        {
            get { return selectedTab; }
            set
            {
                selectedTab = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedTab"));
            }
        }


        public ProcessViewModel()
        {
            ButtonCommand = new RelayCommand(new Action<object>(clickbutton));
            depositAmount = "450";
        }

        public void clickbutton(object obj)
        {
            MessageBox.Show("clicked");
            SelectedTab = 1;
        }
    }

CustomerViewModel.cs

 class CustomerViewModel: ProcessViewModel, INotifyPropertyChanged
    {
        private string customerName;

        public string CustomerName
        {
            get { return customerName; }
            set { customerName = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CustomerName"));
            }
        }
        public CustomerViewModel()
        {
            CustomerName = "Alex";
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

Before adding binding for selected index there were no issues.

Upvotes: 1

Views: 1178

Answers (1)

Keith Stein
Keith Stein

Reputation: 6764

Your problem is that you're setting TabControl.DataContext. DataContext is inherited, so all the controls inside it are now using processVM as their binding source instead of MainWindowViewModel.

Instead of setting TabControl.DataContext, change the SelectedIndex binding to this:

SelectedIndex="{Binding processVM.SelectedTab, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

Upvotes: 2

Related Questions