Reputation: 709
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;
}
Upvotes: 1
Views: 795
Reputation: 13669
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.
Upvotes: 2