Использование разных источников привязки данных в ListBox и ContextMenus - PullRequest
1 голос
/ 09 марта 2011

Вот XAML:

                <ListBox ItemsSource="{Binding Documents}" BorderBrush="{x:Null}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="{Binding Title}" FontSize="12" FontWeight="Bold" />
                            <TextBlock Text="{Binding ID}" FontSize="10" FontStyle="Italic" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>

                <ListBox.ContextMenu>
                    <ContextMenu ItemsSource="{Binding CategoryList}">
                        <ContextMenu.ItemTemplate>
                            <DataTemplate>
                                <MenuItem Command="{Binding AddDocumentToCategoryContextMenuCommand}" Header="{Binding Category.Name}" />
                            </DataTemplate>
                        </ContextMenu.ItemTemplate>
                    </ContextMenu>
                </ListBox.ContextMenu>

            </ListBox>

Хорошо, поэтому ItemSource ListBox привязан к коллекции документов в виртуальной машине и правильно отображает заголовки и идентификаторы

ItemSource контекстного меню привязанв коллекцию CategoryList в ВМ и правильно отображает список категорий.

Проблема, с которой я столкнулся, связана с привязкой команд:

Command="{Binding AddDocumentToCategoryContextMenuCommand}"

Поскольку ItemSource для ContextMenu уже установлен,он пытается получить AddDocumentToCategoryContextMenuCommand из CategoryList.Очевидно, что команда не существует, она является членом виртуальной машины.

Я не хочу никаких ссылок на виртуальные машины или модели в XAML.Все построено с использованием Unity, а VM-View связан с App.xaml:

<Application.Resources>
    <DataTemplate DataType="{x:Type vms:FeedViewModel}">
        <views:FeedView/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type vms:DocumentsViewModel}">
        <views:DocumentsView/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type vms:ManagementViewModel}">
        <views:ManagementView/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type dev:DevelopmentViewModel}">
        <dev:DevelopmentView />
    </DataTemplate>
</Application.Resources>

Как я могу привязать данные к члену виртуальной машины из ContextItem.

Спасибо.

ОБНОВЛЕНО редактирование # 1 начинается Здесь

Вот обновленный xaml (но все еще не работает, но получено некоторое понимание):

<ListBox ItemsSource="{Binding Documents}" x:Name="Results" BorderBrush="{x:Null}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="{Binding Title}" FontSize="12" FontWeight="Bold" />
                            <TextBlock Text="{Binding ID}" FontSize="10" FontStyle="Italic" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>

                <ListBox.ContextMenu>
                    <ContextMenu ItemsSource="{Binding CategoryList}">
                        <ContextMenu.ItemTemplate>
                            <DataTemplate>
                                <MenuItem Command="{Binding ElementName=Results, Path=DataContext.AddDocumentToCategoryContextMenuCommand}" Header="{Binding Category.Name}" />
                            </DataTemplate>
                        </ContextMenu.ItemTemplate>
                    </ContextMenu>
                </ListBox.ContextMenu>

            </ListBox>

У меня естьПример работы для простого примера, который не использует ContextMenu.Похоже, что ContextMenu (даже если он присоединен к ListBox) не является частью визуального дерева пользовательского элемента управления.Привязка всегда возвращается null / not found.Я думаю, что ContextMenu, потому что это плавающее «окно» построено в своем собственном дереве и поэтому не может найти вызов ListBox «Results» для доступа к DataContext ListBox.

Есть какие-нибудь мысли по этому поводу?Любые рекомендации о том, как с этим справиться?

Edit # 2 начинается здесь

Если вам интересно, разобрался с ответом на обязательный вопрос:

Эта привязка работает:

Command="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AddDocumentToCategoryContextMenuCommand}

Надеюсь, что это поможет другим с тем же вопросом.

Последнее обновление для полноты.

В порядкечтобы команда знала, по какому пункту контекстного меню щелкнули, мне пришлось немного изменить xaml (глупый недосмотр):

                <ListBox.ContextMenu>
                    <ContextMenu x:Name="Context" ItemsSource="{Binding CategoryList}">
                        <ContextMenu.ItemTemplate>
                            <DataTemplate>
                                <MenuItem Command="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AddDocumentToCategoryContextMenuCommand}"  
                                            CommandParameter="{Binding Category.ID}"
                                            Header="{Binding Category.Name}" />
                            </DataTemplate>
                        </ContextMenu.ItemTemplate>
                    </ContextMenu>
                </ListBox.ContextMenu>

Опять же, надеюсь, это поможет другим.

1 Ответ

2 голосов
/ 09 марта 2011

Используйте свойство ElementName привязки , чтобы указать это.Вы бы получили что-то вроде этого:

Command="{Binding ElementName=ViewModelObject 
                  Path=AddDocumentToCategoryContextMenuCommand}"
...