Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the selected tab in the view model (wpf)

I have one main view which has a tab control. When a tab is selected, it calls the appropriate view to display. I have a function in view model which has to know which tab was selected to preform an operation. How do I achieve this? How will the view model know which tab is selected?

like image 956
nan Avatar asked Dec 03 '14 03:12

nan


2 Answers

Quite simply:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication2"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:TestViewModel x:Key="MainViewModel"/>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <TabControl DataContext="{StaticResource MainViewModel}" 
                    SelectedIndex="{Binding Selected}" 
                    Grid.Row="0" 
                    x:Name="TestTabs">
            <TabItem Header="Section 1"/>
            <TabItem Header="Section 2"/>
            <TabItem Header="Section 3"/>
        </TabControl>
        <Button Content="Check 
                Selected Index" 
                Grid.Row="1" 
                x:Name="TestButton" 
                Click="TestButton_OnClick"/>
    </Grid>
</Window>

The model is defined here, declaratively, as a data context. The selectedindex property is bound to the model so any time it changes, the propery it is mapped to on the view model will also change

class TestViewModel : INotifyPropertyChanged
{
    private int _selected;
    public int Selected
    {
        get { return _selected; }
        set
        {
            _selected = value;
            OnPropertyChanged("Selected");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

This implements INotifyPropertyChanged so the view will register with it. In the handler here, I output the value of Selected to show the as you change them.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void TestButton_OnClick(object sender, RoutedEventArgs e)
    {
        var vm = TestTabs.DataContext as TestViewModel;
        MessageBox.Show(string.Format("You selected tab {0}", vm.Selected));
    }
}

This gets the viewmodel and then shows us that the properties were in fact updated.

like image 129
Sinaesthetic Avatar answered Sep 22 '22 14:09

Sinaesthetic


In View, you put SelectedIndex property on TabControl:

xmlns:cal="http://www.caliburnproject.org"

<TabControl cal:Message.Attach="[SelectionChanged] = [OnTabSelectionChanged()]"
                    SelectedIndex="{Binding SelectedIndexTab}">
            <TabItem Header="Tab 1"/>
            <TabItem Header="Tab 2"/>
</TabControl>

In ViewModel, you declare a public property name SelectedIndexTab and OnTabSelectionChanged() method to operate.

public int SelectedIndexTab { get; set; }

In this example, I use Caliburn to catch SelectionChange event of TabControl.

like image 40
apo Avatar answered Sep 22 '22 14:09

apo