RibbonApplicationMenu命令中的不同行为

时间:2014-01-20 22:02:03

标签: wpf mvvm ribbon

我的应用程序中有一个类似于此示例的RibbonApplicationMenu:

<RibbonApplicationMenu>
    <RibbonApplicationMenuItem Header="Open Project..." Command="{Binding OpenProjectCommand}" />
    <RibbonApplicationMenuItem Header="Save Project..." Command="{Binding SaveProjectCommand}" />
    <RibbonApplicationMenuItem Header="Exit" Command="{Binding CloseWindowCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RibbonWindow}}}" />
    <RibbonApplicationMenu.FooterPaneContent>
        <RibbonButton Label="Exit" Command="{Binding CloseWindowCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RibbonWindow}}}" />
    </RibbonApplicationMenu.FooterPaneContent>
</RibbonApplicationMenu>

private void CloseWindow (Object parameter)
{
    ((Window) parameter).Close();
}

在示例中,有一个RibbonApplicationMenuItem和RibbonButton项绑定到同一个命令并传递了相同的参数。该命令执行CloseWindow()函数。我发现很奇怪的是,当单击RibbonApplicationMenuItem时,该函数的参数是指向RibbonWindow的指针。但是,单击RibbonButton时,函数的参数为​​null。

为什么行为会有所不同?

1 个答案:

答案 0 :(得分:1)

FooterPaneContent设置为另一个控件(RibbonButton)会弄乱逻辑树,这就是RelativeAncestor不起作用的原因。

换句话说,即使您绑定到按钮本身,使用LogicalTreeHelper遍历也不起作用(VisualTreeHelper也不起作用,因为窗格是PopUp并且生活在另一个可视树中):

<r:RibbonApplicationMenu.FooterPaneContent>
    <r:RibbonButton Label="Exit" Command="{Binding CloseWindowCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}" />
</r:RibbonApplicationMenu.FooterPaneContent>
private void CloseWindow(object parameter)
{
    RibbonButton _button = (RibbonButton)parameter;

    // _appMenu will be null
    DependencyObject _appMenu = LogicalTreeHelper.GetParent(_button);
}

所以,你的选择是:

  1. 绑定到self并使用_button.Ribbon属性获取Ribbon并遍历逻辑树以获取RibbonWindow

  2. 设置ContentTemplate而不是Content。小心传播DataContext虽然。

  3. <r:RibbonApplicationMenu.FooterPaneContentTemplate>
        <DataTemplate>
            <r:RibbonButton Label="Exit" DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type r:RibbonApplicationMenu}}, Path=DataContext}" Command="{Binding Path=CloseWindowCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type r:RibbonWindow}}}" />
        </DataTemplate>
    </r:RibbonApplicationMenu.FooterPaneContentTemplate>
    
       private void CloseWindow(object parameter)
       {
            ((Window)parameter).Close();
       }