Как вы привязываете пункты меню к ContextMenu в silverlight, включая значок

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

<Button>
    <controlsInputToolkit:ContextMenuService.ContextMenu>
        <controlsInputToolkit:ContextMenu ItemsSource="{Binding MenuItems}">
            <controlsInputToolkit:ContextMenu.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" />
                </DataTemplate>
            </controlsInputToolkit:ContextMenu.ItemTemplate>
        </controlsInputToolkit:ContextMenu>
    </controlsInputToolkit:ContextMenuService.ContextMenu>
</Button>

но есть одна проблема: ItemTemplate представляет текстовую область пункта меню, и, насколько мне известно, вы не можете установить значок

поэтому я попытался выполнить привязку через ItemContainerStyle, как в приведенном ниже примере.

<Button>
    <controlsInputToolkit:ContextMenuService.ContextMenu>
        <controlsInputToolkit:ContextMenu ItemsSource="{Binding MenuItems}">
            <controlsInputToolkit:ContextMenu.ItemContainerStyle>
                <Style TargetType="controlsInputToolkit:MenuItem">
                    <Setter Property="Header" Value="{Binding Name}"/>
                </Style>
            </controlsInputToolkit:ContextMenu.ItemContainerStyle>
        </controlsInputToolkit:ContextMenu>
    </controlsInputToolkit:ContextMenuService.ContextMenu>
</Button>

но сильверлайту это не нравится

Любые идеи?


person Lightweight    schedule 29.10.2010    source источник


Ответы (3)


Я создаю контекстное меню программно и устанавливаю содержимое к свойству MenuItem.Header, кажется, отлично работает для изображений. Существует множество примеры настройки текста.

person Erik Noren    schedule 29.10.2010
comment
Программное создание меню будет работать, но это нарушает мой шаблон mvvm, поэтому я ищу способ сделать это только с привязкой - person Lightweight; 31.10.2010

Вместо этого попробуйте использовать это меню с открытым исходным кодом:

http://sl4popupmenu.codeplex.com

Шаблон позволяет привязывать изображения напрямую. Надеюсь это поможет.

person Ziad    schedule 05.11.2010

У меня был тот же вопрос, и хотя я не нашел ответа, который хотел, я нашел обходной путь, который хорошо удовлетворил мои потребности. Я подумал, что тебе может понравиться это увидеть, даже спустя долгое время после свершившегося факта.

Похоже, что если ItemsSource класса ContextMenu содержит MenuItem объектов, то иконка попадает туда, где ей и место. Я, как и вы, использовал модель представления и не знал, что вводить логику пользовательского интерфейса в мой класс модели представления.

Вместо этого я реализовал преобразователь значений для преобразования моей модели представления в MenuItem объекты. Выглядело это примерно так:


XAML:

<UserControl.Resources>
    <local:DelegatedValueConverter
        x:Key="LocalContextItemConverter"
        Converting="OnBindingContextMenu" />
</UserControl.Resources>

...

<toolkit:ContextMenu
    ItemsSource="{Binding ContextMenuItems, Converter={StaticResource LocalContextItemConverter}}" />

Код программной части C#

private void OnBindingContextMenu(object sender, ValueConvertingEventArgs e)
{
    var dataitems = e.Value as IEnumerable< NavigationItemViewModel >;
    if (dataitems != null)
    {
        var items = dataitems.Select(data => new MenuItem()
        {
            Header = data.Title,
            Icon = data.Icon,
            Tag = data
        }).ToList();
        var handler = new RoutedEventHandler(this.OnContextMenuClick);
        items.ForEach(item => item.Click += handler);
        e.Result = items
    }
}

private void OnContextMenuClick(object sender, RoutedEventArgs e)
{
}

Обсуждение

DelegatedValueConverter — это то, что я подробно описываю здесь, но это не очень важно. Вы можете свернуть свой собственный преобразователь значений и использовать его вместо этого.

Свойство Title моей модели представления — это строка, а Icon — экземпляр Image. Я использую свойство Tag пункта меню, чтобы сохранить ссылку на мою модель представления, чтобы я мог ссылаться на невизуальные данные в ней во время события щелчка.

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

Надеюсь, это поможет!

person kbrimington    schedule 05.03.2011