Reputation: 974
I have a RibbonApplicationMenu in my app similar to this example:
<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();
}
In the example there are a RibbonApplicationMenuItem and RibbonButton item bound to the same command and having the same parameter passed. The command executes the CloseWindow() function. What I find curious is that when the RibbonApplicationMenuItem is clicked, the parameter to the function is the pointer to the RibbonWindow. However, when the RibbonButton is clicked, the parameter to the function is null.
Why would the behavior be different?
Upvotes: 1
Views: 547
Reputation: 411
Setting FooterPaneContent
to be another control (RibbonButton
) messes up the logical tree that's why RelativeAncestor
doesn't work.
In the other words even if you bind to the button itself, traversing with LogicalTreeHelper
won't work (VisualTreeHelper
won't work either since the pane is a PopUp
and lives in a separate visual tree):
<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);
}
So, your options are:
Bind to self and use _button.Ribbon property to get the Ribbon
and traverse up the logical tree to get the RibbonWindow
.
Set ContentTemplate
instead of Content
. Be careful to propagate the DataContext
though.
<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();
}
Upvotes: 1