问题
I want to know how to attach command to RibbonMenuButton item. The following is my initial attempt but the command is never called.
<ribbon:RibbonWindow x:Class="RibbonMenuDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
Title="MainWindow"
x:Name="RibbonWindow"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ribbon:Ribbon x:Name="Ribbon">
<ribbon:RibbonTab x:Name="HomeTab"
Header="Home">
<ribbon:RibbonGroup x:Name="Group1"
Header="Map">
<ribbon:RibbonMenuButton ItemsSource="{Binding Regions}"
LargeImageSource="Images\LargeIcon.png"
Label="Regions" >
<ribbon:RibbonMenuButton.ItemContainerStyle >
<Style TargetType="MenuItem" >
<Setter Property="Command" Value="{Binding RegionChangeCommand}" />
<Setter Property="CommandParameter" Value="{Binding Label}"></Setter>
</Style>
</ribbon:RibbonMenuButton.ItemContainerStyle>
</ribbon:RibbonMenuButton>
</ribbon:RibbonGroup>
</ribbon:RibbonTab>
</ribbon:Ribbon>
</Grid>
</ribbon:RibbonWindow>
here is my code
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Windows.Controls.Ribbon;
using System.ComponentModel;
using System.Diagnostics;
namespace RibbonMenuDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : RibbonWindow
{
RelayCommand regionChangeCommand;
public MainWindow()
{
InitializeComponent();
this.DataContext = new Map();
}
public RelayCommand RegionChangeCommand
{
get
{
if (regionChangeCommand == null)
regionChangeCommand = new RelayCommand(param => OnRegionChange(param), param => false);
return regionChangeCommand;
}
}
private void OnRegionChange(object param)
{
var val = (string)param;
MessageBox.Show(val);
}
}
public class Map
{
public Map()
{
Regions = new List<string>
{
"EAST", "North", "West", "South"
};
}
public List<string> Regions
{
get;
set;
}
}
public class RelayCommand : ICommand
{
readonly Action<object> execute;
readonly Predicate<object> canExecute;
/// <summary>
/// create new simple command
/// </summary>
/// <param name="execute">execute handler</param>
/// <param name="canExecute">predicate to determin if can excute</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
{
if (execute == null)
throw new ArgumentNullException("execute handler required");
this.execute = execute;
Predicate<object> v = (x) => { return true; };
this.canExecute = canExecute ?? v;
}
public void Execute(object parameter)
{
this.execute(parameter);
}
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
}
回答1:
Solved like this:
<ribbon:RibbonMenuButton DataContext="{Binding .}" ItemsSource="{Binding Regions}"
LargeImageSource="Images\LargeIcon.png" Label="Regions">
<ribbon:RibbonMenuButton.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding DataContext.RegionChangeCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type
ribbon:RibbonMenuButton}}}" />
<Setter Property="CommandParameter" Value="{Binding Label}"></Setter>
</Style>
</ribbon:RibbonMenuButton.ItemContainerStyle>
</ribbon:RibbonMenuButton>
Adapted from the Click event routing on RibbonButton under RibbonMenuButton? page on the Visual Studio Forum on MSDN.
来源:https://stackoverflow.com/questions/4178118/how-to-attach-command-to-wpf-ribbonmenubutton