Привязка IsChecked MenuItem к isSelected TabItem

В основном я сталкиваюсь с той же проблемой, что и описанная в Binding MenuItem IsChecked to IsSelected TabItem с динамическими вкладками Я настроил TabControl так, чтобы он имел собственную модель представления. Также у меня было меню, которое привязывалось к тому же источнику. Произошло то, что привязка menuItem isChecked к isSelected больше не работала. I thought IsSelected can not be found as there's no such property in viewModel

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

Я попытался использовать предложенное решение для создания списка TabItem, но получаю сообщение об ошибке Unable to cast object of type TabData to type TabItem. Ниже мой xaml и конвертер. Я думал, что это не удастся, потому что во время построения TabControl.items вернет экземпляр модели представления вместо UIControl TabItem; Любые предложения, как сделать привязку здесь?

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;
}

введите здесь описание изображения


person baozi    schedule 14.11.2014    source источник


Ответы (1)


вот изменения, основанные на предоставленном проекте

удалить следующее из привязки, это не требуется

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

изменить сеттер в стиле TabMenuItemxxx

от

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

to

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

добавьте следующий сеттер в стиль для TargetType="{x:Type TabItem}"

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

измените класс TabData следующим образом

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));
    }
}

это все, что вам нужно изменить в своем проекте, чтобы синхронизировать элементы меню, отмеченные флажком, чтобы выбрать элемент вкладки.

для вашей второй проблемы с закрытием элемента вкладки вы можете исправить ее, изменив кнопку закрытия

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

to

CommandParameter="{Binding}"

пример проекта TabControlSyncWithMenuItems.zip

Дайте мне знать результаты.

person pushpraj    schedule 21.11.2014
comment
Тай, очень красивый ответ! Как CommandParameter="{Binding}" делает вывод, что TabItem принадлежит самому себе? - person baozi; 22.11.2014
comment
@baozi, {Binding} относится к объекту, привязанному к элементу, который в данном случае является экземпляром класса TabData. см. Расширение привязки разметки для получения дополнительной информации. Неквалифицированный синтаксис {Binding} и синтаксис пути привязки для более подробной информации о том же. Я рад, решение помогло вам решить некоторые из ваших проблем. последнее, но не менее важное: удачного кодирования :) - person pushpraj; 22.11.2014