Динамическая привязка к командам ViewModel в MenuItem окна - PullRequest
5 голосов
/ 27 мая 2011

Работа над приложением WPF с использованием структуры MVVM.

Мое окно отображает меню и текущую модель просмотра. В одном из элементов Menu Menu я хочу перечислить некоторые команды, найденные в текущей ViewModel. Команды, перечисленные в меню, будут меняться в зависимости от модели представления.

Я получил это, чтобы работать просто отлично, но стиль испорчен - Command MenuItems находятся в другом окне меню или что-то в этом роде. Я прикреплю скриншот.

Я обернул объекты ICommand ViewModel (в данном случае RelayCommands) в CommandViewModel, которые представляют команду и строку отображения, которую я хочу, в меню. Эти CommandViewModels находятся в списке: CurrentWorkspace.AdditionalOptionsCommands.

Вот XAML для меню. Как я уже сказал, это работает, показывает правильные элементы и команды выполняются. Дисплей просто неверный - кто-нибудь может подсказать почему и как это исправить? Смотрите скриншот.

<Menu>
    <MenuItem Header="_Additional Options..." ItemsSource="{Binding Path=CurrentWorkspace.AdditionalOptionsCommands}">
        <MenuItem.ItemTemplate>
            <DataTemplate DataType="{x:Type vm:CommandViewModel}">
                <MenuItem Header="{Binding Path=DisplayText}" Command="{Binding Path=Command}"/>
            </DataTemplate>
        </MenuItem.ItemTemplate>
    </MenuItem>
    <MenuItem Header="_Testing">
        <MenuItem Header="This looks right" />
        <MenuItem Header="This looks right" />
    </MenuItem>   
</Menu>  

Текущий внешний вид:

Current Appearance

Желаемый внешний вид:

Desired Appearance

1 Ответ

8 голосов
/ 27 мая 2011

Это связано с тем, что при указании пунктов меню с помощью ItemsSource каждый элемент автоматически оборачивается в объект MenuItem.Таким образом, содержимое, определенное в DataTemplate (MenuItem элемент), будет упаковано в еще один MenuItem.

Что нужно сделать вместо определения DataTemplate, это определить стиль дляMenuItem, где вы устанавливаете привязки к свойствам модели представления и используете этот стиль как ItemContainerStyle на родительском MenuItem:

<Window.Resources>
    <Style x:Key="CommandMenuItemStyle"
           TargetType="{x:Type MenuItem}">
         <Setter Property="Header"
                 Value="{Binding Path=DisplayText}"/> 
         <Setter Property="Command"
                 Value="{Binding Path=Command}"/>
    </Style>
</Window.Resources>
...
<Menu>
    <MenuItem Header="_Additional Options..." 
              ItemsSource="{Binding Path=CurrentWorkspace.AdditionalOptionsCommands}" 
              ItemContainerStyle="{StaticResource CommandMenuItemStyle}"/>
    <MenuItem Header="_Testing">
        <MenuItem Header="This looks right" />
        <MenuItem Header="This looks right" />
    </MenuItem>   
</Menu>   

См. http://drwpf.com/blog/2008/03/25/itemscontrol-i-is-for-item-container/ для подробного объяснениякак контейнеры элементов работают с элементами управления ItemsControl.

...