Проблема с привязкой WPF Menu к ItemsSource - PullRequest
3 голосов
/ 11 июня 2010

Я бы хотел избежать необходимости создавать меню вручную в XAML или коде, связываясь со списком ICommand -приобретенных объектов. Однако у меня возникла небольшая проблема, когда в результирующем меню есть два уровня пунктов меню (то есть каждый MenuItem содержится в MenuItem):

альтернативный текст http://i47.tinypic.com/j63lg2.png

Я предполагаю, что это происходит потому, что WPF автоматически генерирует MenuItem для моей привязки, но "просмотрщик", который я использую, на самом деле уже равен a MenuItem (он получен из 1013 *):

<ContextMenu
    x:Name="selectionContextMenu"
    ItemsSource="{Binding Source={x:Static OrangeNote:Note.MultiCommands}}"
    ItemContainerStyleSelector="{StaticResource separatorStyleSelector}">
    <ContextMenu.ItemTemplate>
        <DataTemplate>
            <Viewers:NoteCommandMenuItemViewer
                CommandParameter="{Binding Source={x:Static OrangeNote:App.Screen}, Path=SelectedNotes}" />
        </DataTemplate>
    </ContextMenu.ItemTemplate>
</ContextMenu>

(ItemContainerStyleSelector из http://bea.stollnitz.com/blog/?p=23,, что позволяет мне иметь Separator элементов внутри моего связанного источника.)

Итак, меню привязано к коллекции ICommand с, и для каждого элемента CommandParameter установлена ​​одна и та же глобальная цель (которая является коллекцией, но это не важно).

У меня вопрос, есть ли способ связать это так, чтобы WPF автоматически не оборачивал каждый элемент в MenuItem?

Ответы [ 2 ]

3 голосов
/ 11 июня 2010

К сожалению, лучший способ, который я нашел, чтобы обойти эту проблему, это использовать стиль для MenuItems, а не ItemTemplate.Тогда каждое свойство в стиле может быть привязано к свойствам вашего объекта.Примерно так, например:

<Style x:Key="SelectionContextMenuStyle" TargetType="MenuItem">
    <Setter Property="Header" Value="{Binding Path=Text}" />
    <Setter Property="Command" Value="{Binding Path=Command}" />
    <Setter Property="CommandParameter" Value="{Binding Path=Parameter}" />
</Style>

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

2 голосов
/ 11 июня 2010

Я был бы склонен к созданию подкласса ContextMenu и переопределил GetContainerForItemOverride:

public class ContextMenuWithNoteCommands : ContextMenu
{
  protected virtual DependencyObject GetContainerForItemOverride()
  {
    return new NoteCommandMenuItemViewer();
  }
}

Затем установите привязку CommandParameter в стиле NoteCommandMenuItemViewer или в ContextMenu.ItemContainerStyle, в зависимости от того, что больше подходит.

Это предполагает, что вы не можете просто использовать ItemContainerStyle в обычном MenuItem, чтобы получить желаемый эффект:

<ContextMenu ...>
  <ContextMenu.ItemContainerStyle>
    <Style>
      ...
    </Style>
  </ContextMenu.ItemContainerStyle>
</ContextMenu>
...