Как связать элемент управления ленты с моей моделью представления? - PullRequest
4 голосов
/ 25 августа 2011

Со вчерашнего дня я боролся за создание (как я думал) простой ленты на WPF с использованием MVVM. Я нашел довольно много ссылок в Интернете (и на переполнение стека), но ни одна из них не могла решить мою проблему.

В двух словах, мой вопрос: Я делаю это неправильно или просто невозможно привязать ленту к ViewModel, как я делаю?

В деталях:

Это моя модель для меню: каждая MenuGroup должна отображаться как RibbonGroup , а MenuGroup содержит коллекцию MenuItem который должен отображаться как RibbonButton (внутри соответствующей RibbonGroup , конечно).

using Caliburn.Micro;

namespace MyCompany.Poc.Wpf.Models
{
    public class MenuGroup
    {
        public MenuGroup()
        {
            Items = new BindableCollection<MenuItem>();
        }

        public string Name { get; set; }

        public IObservableCollection<MenuItem> Items { get; set; }
    }
}


using System.Windows.Input;

namespace MyCompany.Poc.Wpf.Models
{
    public class MenuItem
    {
        public MenuGroup Group { get; set; }

        public string Name { get; set; }

        public string Link { get; set; }

        public ICommand OpenMenuUrl { get; set; }
    }
}

Моя ViewModel просто содержит коллекцию этих MenuGroup для привязки в XAML:

public IObservableCollection<MenuGroup> LegacyMenuItems
{
    get { return _legacyMenuItems; }
}

Коллекция заполняется (на данный момент), как только создается экземпляр виртуальной машины, с поддельными данными):

var group1 = new MenuGroup();
group1.Name = "Group 1";
var group2 = new MenuGroup();
group2.Name = "Group 2";

group1.Items.Add(new MenuItem {Group = group1, Link = "http://www.google.co.uk", Name = "Link 1", OpenMenuUrl = OpenMenuUrl});
group1.Items.Add(new MenuItem {Group = group1, Link = "http://www.google.co.uk", Name = "Link 2", OpenMenuUrl = OpenMenuUrl});
group2.Items.Add(new MenuItem {Group = group2, Link = "http://www.google.co.uk", Name = "Link 3", OpenMenuUrl = OpenMenuUrl});
group2.Items.Add(new MenuItem {Group = group2, Link = "http://www.google.co.uk", Name = "Link 4", OpenMenuUrl = OpenMenuUrl});

LegacyMenuItems.Add(group1);
LegacyMenuItems.Add(group2);

Теперь XAML:

<my:Ribbon  DockPanel.Dock="Top">
    <my:RibbonTab Header="Legacy A.I." ItemsSource="{Binding LegacyMenuItems}">
        <my:RibbonTab.ItemTemplate>
            <DataTemplate>
                <my:RibbonGroup Header="{Binding Name}" ItemsSource="{Binding Items}">
                    <my:RibbonGroup.ItemTemplate>
                        <DataTemplate>
                            <my:RibbonButton Label="{Binding Name}" Command="{Binding OpenMenuUrl}" CommandParameter="{Binding Link}"></my:RibbonButton>
                        </DataTemplate>
                    </my:RibbonGroup.ItemTemplate>
                </my:RibbonGroup>
            </DataTemplate>
        </my:RibbonTab.ItemTemplate>
    </my:RibbonTab>

    <my:RibbonTab Header="Static">
        <my:RibbonGroup Name="Administration" Header="Admin">
            <my:RibbonButton Label="Stuffs" Command="{Binding Path=OpenMenuUrl}" CommandParameter="http://www.mycompany.com/somelink"></my:RibbonButton>
            <my:RibbonButton Label="Google" Command="{Binding Path=OpenMenuUrl}" CommandParameter="http://www.google.co.uk"></my:RibbonButton>
        </my:RibbonGroup>
    </my:RibbonTab>

</my:Ribbon>

И что это делает: Doesn't look right, does it... Statically loaded, works like a charm...

Как видите, вкладка «Статические» работает хорошо, а «заголовок» для группы лент («Администратор») отображается в нужном месте.

Теперь "Наследие А.И." На вкладке нет кнопок (в каждой группе должно быть 2 кнопки), и заголовки RibbonGroup отображаются смешно ( ниже, где они должны быть ).

Если вы понимаете, что я делаю не так, пожалуйста, скажите мне :) Я очень новичок в мире WPF, поэтому, очевидно, я не понимаю шаблонов должным образом ...

Несколько фактов, которые помогут вам сделать звонок: - Модель загружена правильно, так как мы видим «Группу 1» и «Группу 2», которые являются частью поддельных данных, загруженных во ViewModel. - Я попробовал RadRibbon от Telerik, и он ведет себя точно так же! Так что, если они не правы в одном и том же месте, проблема должна исходить от меня

Спокойной ночи и удачи:)

Ответы [ 3 ]

1 голос
/ 26 августа 2011

Я использую ленту также в приложении MVVM и решил придерживаться элементов управления, определенных в XAML, связывая их со статическими свойствами ICommand в классах, определенных в моем слое viewmodel. Это очень негибко, но пока работает для меня.

Если вы скачали и установили официальную ленту Microsoft, вы найдете ее источник и несколько примеров:

C: \ Program Files \ Microsoft Ribbon для WPF \ MicrosoftRibbonForWPFSourceAndSamples

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

0 голосов
/ 27 октября 2016

Капитан Некропостер здесь:

У меня была та же проблема рендеринга, и это мое решение

            <HierarchicalDataTemplate DataType="{x:Type navigation:RibbonTabViewModel}" ItemsSource="{Binding Path=Groups}">
                <TextBlock Text="{Binding Path=Title}"></TextBlock>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type navigation:RibbonGroupViewModel}" ItemsSource="{Binding Path=Items}">
                <TextBlock Text="{Binding Path=Title}" ></TextBlock>
            </HierarchicalDataTemplate>
            <DataTemplate DataType="{x:Type navigation:RibbonButtonViewModel}">
                <RibbonButton Label="{Binding Path=Title}" Command="{Binding Path=ClickedCommand}" CommandParameter="{Binding Path=.}"></RibbonButton>
            </DataTemplate>

Для начала у меня была RibbonGroup в качестве содержимого шаблона для моей RibbonGroupViewModel. Благодаря последней версии VS я смог осмотреть живое дерево и найти там проблему.

0 голосов
/ 29 января 2013

У меня была та же проблема вчера, и я изо всех сил пытался найти решение.

Я думаю, что ваша проблема может быть решена с помощью HierarchicalDataTemplate .

<r:Ribbon>
    <r:RibbonTab Header="Legacy A.I." ItemsSource="{Binding LegacyMenuItems}">
        <r:RibbonTab.Style>
            <Style TargetType="{x:Type r:RibbonTab}">
                <Setter Property="ItemsSource" Value="{Binding LegacyMenuItems}" />
                <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <HierarchicalDataTemplate DataType      = "{x:Type r:RibbonGroup}"
                                                  ItemsSource   = "{Binding Items}" >
                            <TextBlock Text="{Binding Name}" />
                        </HierarchicalDataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </r:RibbonTab.Style>
    </r:RibbonTab>
</r:Ribbon>
...