Привязка IsIcheck для MenuItem к IsSelected элемента TabItem с помощью динамических вкладок - PullRequest
0 голосов
/ 01 ноября 2011

У меня есть список элементов вкладок, к которым динамически добавляются представления.Каждый раз, когда пользователь добавляет вид, создается новый элемент вкладки.Сейчас я пытаюсь привязать меню к элементам tabcontrol, чтобы пользователь мог выбрать из меню, какое представление в настоящее время является активным представлением.

Мое меню ограничено следующим образом:

<Menu Background="Transparent">
    <MenuItem Style="{StaticResource TabMenuButtonStyle}" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}, Path=Items}" ItemContainerStyle="{StaticResource TabMenuItem}"></MenuItem>
</Menu>

Это прекрасно работает и дает желаемый эффект (каждый пункт меню представляет собой список всех открытых вкладок).

У меня есть следующий стиль, который связывает пункты меню со свойством IsSelected элементов вкладки:

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

Моя проблема в том, что эта привязка не работает.В сообщении об ошибке привязки указывается, что он не может найти свойство IsSelected для объекта представления.Я не хочу, чтобы он использовал специфическое представление, скорее, я хочу, чтобы он посмотрел на элемент вкладки, к которому в данный момент привязано представление.

Я попробовал следующее, но все еще получаю ошибку привязки:

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

, которая утверждает, что не может найти предка типа TabItem для каждого пункта меню (что имеет смыслтак как предки пункта меню не являются тем, с чем он связан.)

Есть ли какой-либо способ получить доступ к родительскому элементу элемента, который входит в качестве привязки, чтобы я мог привязать его свойства?

Обновление:

По совету Ядына я решил создать конвертер значений и вернуть элементы табуляции.

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

Это делает привязку IsSelected к IsChecked для работы со статическими элементами (TabControls, у которых уже созданы элементы вкладок), но для динамически добавляемых представлений метод Convert никогда не вызывается.Похоже, что TabControl не отправляет обновление связующим элементам, что-то изменилось.Вот как MenuItem теперь подключен:

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

Ответы [ 2 ]

0 голосов
/ 03 ноября 2011

Вот что-то попроще. Определите верхнюю модель представления, которая содержит коллекцию моделей представления, представляющих вкладки и элементы меню, например:

//Not showing here the details of implementing INPC
public class MyCustomCompositeViewModel:INotifyPropertyChanged
{
  public ObservableCollection<CompositeViewItem>CompositeItems{get;set;}
  public CompositeViewItem SelectedItem{get;set;}
}

В представлении привяжите элементы табуляции к коллекции CompositeItems и привяжите выбранный элемент вкладки к selectedItem. Вы можете привязать MenuItems аналогично

Составной элемент представления должен предоставлять такие свойства, как имя элемента (для отображения на вкладке и в меню) и, возможно, дополнительные данные, необходимые представлению для рендеринга. Надеюсь, что это имеет смысл.

0 голосов
/ 01 ноября 2011

TabControl.Items вернет вам представления, так как это то, что вы привязали к вашему TabControl, чтобы иметь динамические представления вкладок.

К сожалению, в TabControl нет свойства, которое можно было бы привязать непосредственно к TabItems. Это фактически ItemContainers для каждого элемента в коллекции Предметов.

Что вы можете сделать, это создать конвертер или что-то в этом роде. Вы можете попробовать использовать myTabControl.ItemContainerGenerator. ContainerFromItem и передать объект представления, чтобы получить фактический TabItem, который его обертывает. Тогда ваша привязка IsSelected будет работать.

Вы можете рассмотреть возможность привязки непосредственно к самому TabControl вместо свойства Items. Тогда конвертер может легко сделать вышеуказанный вызов ContainerFromItem. Затем вам нужно будет вернуть List<TabItems> из конвертера, перечислив свойство Items самостоятельно (вызывая ContainerFromItem для каждого).

В любом случае, надеюсь, вы попадете на правильный путь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...