Search code examples
c#wpfmvvmtabcontroltabitem

TabControl Command binding


I am using this code following code taken from Stackoverflow.

I want to transfer a string from one view model to another one on SelectionChanged event. But when I click on Tab2, I get Tab2 message box, but when I click on Tab1, I get both the message boxes indicating that both are getting executed. The same when I click Tab1, both message boxes are seen.

MainView.xaml

<TabControl>
 <TabItem Header="My tab 1" Selector.IsSelected="{Binding IsMyTab1Selected}"> ... </TabItem>
 <TabItem Header="My tab 2" Selector.IsSelected="{Binding IsMyTab2Selected}"> ... </TabItem>
</TabControl>

MainViewModel.cs

public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) {
 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

public MainViewModel() {
 PropertyChanged += handlePropertyChanged;
}

public bool IsMyTab1Selected {
 get { return _IsMyTab1Selected ; }
 set {
  if (value != _IsMyTab1Selected ) {
   _IsMyTab1Selected = value;
   OnPropertyChanged("IsMyTab1Selected ");
  }
 }
}
private bool _IsMyTab1Selected = false;

public bool IsMyTab2Selected {
 get { return _IsMyTab2Selected ; }
 set {
  if (value != _IsMyTab2Selected ) {
   _IsMyTab2Selected = value;
   OnPropertyChanged("IsMyTab2Selected ");
  }
 }
}
private bool _IsMyTab2Selected = false;

private void handlePropertyChanged(object sender, PropertyChangedEventArgs e) {
 if (e.PropertyName == "IsMyTab1Selected") {
   MessageBox.Show("Tab_1 Clicked!");
 } else if (e.PropertyName == "IsMyTab2Selected") {
   MessageBox.Show("Tab_2 Clicked!");
 }
}

I am not able to get the mutually exclusiveness, point me where I am wrong.


Solution

  • Option 1

    you can change the setters to only call OnPropertyChanged(..) when the value is true:

    public bool IsMyTab1Selected
    {
        get { return _IsMyTab1Selected; }
        set
        {
            if (value != _IsMyTab1Selected)
            {
                _IsMyTab1Selected = value;
                if (_IsMyTab1Selected)
                    OnPropertyChanged("IsMyTab1Selected");
            }
        }
    }
    
    public bool IsMyTab2Selected
    {
        get { return _IsMyTab2Selected; }
        set
        {
            if (value != _IsMyTab2Selected)
            {
                _IsMyTab2Selected = value;
                if(_IsMyTab2Selected)
                    OnPropertyChanged("IsMyTab2Selected");
            }
        }
    }
    

    Option 2

    Or you can check in your handlePropertyChange() if the value is true like this

    private void handlePropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "IsMyTab1Selected")
        {
            if(IsMyTab1Selected)
                MessageBox.Show("Tab_1 Clicked!");
        }
        else if (e.PropertyName == "IsMyTab2Selected")
        {
            if(IsMyTab2Selected)
                MessageBox.Show("Tab_2 Clicked!");
        }
    }