Binding MenuItem's IsChecked to TabItem's isSelected

779 views Asked by At

Basically I am facing the same problem as describled at Binding MenuItem's IsChecked to TabItem's IsSelected with dynamic tabs I customed the TabControl to have its own viewModel, Also I had a menu which binds to the same source. What happened is Binding menuItem's isChecked to isSelected did not work any more. I thought IsSelected can not be found as there's no such property in viewModel

<Setter Property="IsChecked" Value="{Binding IsSelected, Mode=TwoWay}" />

I tried to use the solution suggested to construct a list of TabItem but I get the error Unable to cast object of type TabData to type TabItem. Below is my xaml and converter. I thought it fails because during the construction TabControl.items will return the viewmodel instance instead of the UIControl TabItem; Any suggestions how to do a binding here?

XAML

<Menu Background="Transparent">
    <MenuItem
         Style="{StaticResource TabMenuButtonStyle}"
         ItemsSource="{Binding RelativeSource=
            {RelativeSource FindAncestor, 
            AncestorType={x:Type TabControl}}, 
            Path=Items,Mode=OneWay,NotifyOnSourceUpdated=True,Converter={StaticResource TabControlItemConverter}}"
         ItemContainerStyle="{StaticResource TabMenuItemxxx}">
    </MenuItem>
</Menu>

C#

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    ItemCollection ic = (ItemCollection)value;
    List<TabItem> tabItems = new List<TabItem>();
    foreach (var obj in ic)
    {
        tabItems.Add((TabItem)obj);
    }
    return tabItems;
}

enter image description here

1

There are 1 answers

2
pushpraj On BEST ANSWER

here are the changes bases on the provided project

remove the following from the binding, it is not required

,Mode=OneWay,NotifyOnSourceUpdated=True,Converter={StaticResource TabControlItemConverter}

modify setter in style TabMenuItemxxx

from

<Setter Property="IsChecked" Value="{Binding Path=IsSelected, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=TabItem}}" />

to

<Setter Property="IsChecked" Value="{Binding Path=IsSelected, Mode=TwoWay/>

add the following setter in the style for TargetType="{x:Type TabItem}"

<Setter Property="IsSelected" Value="{Binding IsSelected}" />

modify the TabData class as follows

public class TabData : INotifyPropertyChanged
{
    private bool isselected;
    public string Header { get; set; }
    public object Content { get; set; }
    public bool IsEnabled { get; set; }
    public bool IsSelected
    {
        get { return isselected; }
        set
        {
            if (ViewModel.CurrentItem.IsSelected && ViewModel.CurrentItem != this)
            {
                ViewModel.CurrentItem.IsSelected = false;
            }
            isselected = value;
            RaisePropertyChanged("IsSelected");

            if (ViewModel.CurrentItem != this)
                ViewModel.CurrentItem = this;

        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

this is all you need to change in your project to sync menu items's is checked to tab item's is selected.

for your second issue about closing the tab item, you can fix it by changing the close button's

CommandParameter="{Binding SelectedItem,ElementName=tabControl}"

to

CommandParameter="{Binding}"

sample project TabControlSyncWithMenuItems.zip

Let me know the results.