Wpf 如何将功能区控件绑定到ViewModel?

Wpf 如何将功能区控件绑定到ViewModel?,wpf,mvvm,viewmodel,ribbon,caliburn.micro,Wpf,Mvvm,Viewmodel,Ribbon,Caliburn.micro,从昨天开始,我一直在努力使用MVVM在WPF上构建一个(我所认为的)简单的功能区。 我在互联网上(和堆栈溢出)找到了不少链接,但没有一个能真正解决我的问题 简而言之,我的问题是:我做错了吗,还是像我这样将功能区绑定到ViewModel是完全不可能的? 详情如下: 这是我的菜单模型:每个MenuGroup都应该呈现为RibbonGroup,MenuGroup包含一组MenuItem,这些MenuItem应该呈现为RibbonButton(当然是在各自的RibbonGroup内) 现在,XAML:

从昨天开始,我一直在努力使用MVVM在WPF上构建一个(我所认为的)简单的功能区。 我在互联网上(和堆栈溢出)找到了不少链接,但没有一个能真正解决我的问题

简而言之,我的问题是:我做错了吗,还是像我这样将功能区绑定到ViewModel是完全不可能的?

详情如下: 这是我的菜单模型:每个MenuGroup都应该呈现为RibbonGroup,MenuGroup包含一组MenuItem,这些MenuItem应该呈现为RibbonButton(当然是在各自的RibbonGroup内)

现在,XAML:

public IObservableCollection<MenuGroup> LegacyMenuItems
{
    get { return _legacyMenuItems; }
}
<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>

以及它所呈现的内容:

如您所见,“静态”选项卡工作正常,功能区组(“管理员”)的“标题”显示在正确的位置

现在,“Legacy A.I.”选项卡,没有按钮(每组中应该有2个按钮),RibbonGroup标题显示得很有趣(在它们应该位于的下方)

如果你有任何关于我做错了什么的线索,请告诉我:) 我是WPF世界的新手,所以我显然不太理解模板制作

一些事实可以帮助你打电话: -模型加载正确,因为我们可以看到“组1”和“组2”,它们是ViewModel中加载的伪数据的一部分 -我试过Telerik的RadRibbon,它的性能完全一样!因此,除非他们在同一个地方都错了,否则问题一定来自我


晚安,祝你好运:)

我还在MVVM应用程序中使用ribbon,并决定坚持使用XAML中定义的控件,将它们链接到viewmodel层中定义的类中的静态ICommand属性。这是非常不灵活的,但到目前为止对我有效

如果您已经下载并安装了官方Microsoft Ribbon,您将在以下位置找到它的源代码和一些示例:

C:\Program Files\Microsoft Ribbon for WPF\wpfSource和Samples的MicrosoftRibbon


这包括一个同样实现MVVM的示例。这使用了一种完全不同的方法,虽然a可能不是您所需要的,但我认为仔细检查一下可能会有所帮助。

我昨天也遇到了同样的问题,为找到解决方案付出了很多努力

我认为您的问题可以通过HierarchycalDataTemplate解决

<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>

海报如下:

我有同样的渲染问题,这是我的解决方案

            <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,我能够检查活动树并找到问题所在。

您需要做的第一件事是打开用于数据绑定的调试消息:下一步,重新运行并检查输出窗口,看看有什么错误。@Will:期待看到您的答案。@Den:抱歉,我无法回答以前的问题。你知道,我不得不花我仅有的一点时间来处理国旗。如果您想知道为什么不鼓励在其他网站上发布完整的解决方案,我建议您在网站上询问。您可以提供一些关于
HierarchycalDataTemplate
HierarchycalDataTemplate
在WPF中非常常见的参考资料,但何时使用它们并不明显,这就是我首先回答问题的原因;)
<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>
            <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>