I am unable to bind the command of a MenuFlyoutItem to a RelayCommand on my ViewModel. I've tried every way I could think of, ElementName, RelativeSource, etc. Can anyone show me what I'm doing wrong? The other two bindings shown in the code below work. It is only the command binding that doesn't. I mean I have set a breakpoint in the OnFilterListCommand method that is called by the RelayCommand. Execution never reaches that breakpoint when I click on a menu flyout item.
<wct:DataGridComboBoxColumn.HeaderStyle>
<Style TargetType="controlsprimitives:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<TextBlock Text="Company" TextWrapping="Wrap"/>
<Button HorizontalAlignment="Right" x:Name="MyButton" Content="test">
<i:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:InvokeCommandAction Command="{Binding ElementName=thePage, Path=DataContext.OpenFlyoutCommand}" CommandParameter="{Binding ElementName=MyButton}"/>
</core:EventTriggerBehavior>
</i:Interaction.Behaviors>
<FlyoutBase.AttachedFlyout>
<Flyout helpers:BindableFlyout.ItemsSource="{Binding ElementName=theView, Path=DataContext.SourceForCompaniesList}" x:Name="theFlyout">
<helpers:BindableFlyout.ItemTemplate>
<DataTemplate>
<MenuFlyoutItem Text="{Binding CompanyName}" Command="{Binding Path=DataContext.FilterListCommand, ElementName=theView}" IsTapEnabled="True"/>
</DataTemplate>
</helpers:BindableFlyout.ItemTempla
</Flyout>
</FlyoutBase.AttachedFlyout>
Here is the applicable code from the ViewModel.
private RelayCommand<object> _filterListCommand;
public RelayCommand<object> FilterListCommand => _filterListCommand
?? (_filterListCommand = new RelayCommand<object>(OnFilterListCommand));
private void OnFilterListCommand(object obj)
{
string selectedCompany = obj as string;
...
}
I'm using Jerry Nixon's solution to add an ItemsSources property to FlyoutMenu:
public class BindableFlyout : DependencyObject
{
#region ItemsSource
public static IEnumerable GetItemsSource(DependencyObject obj)
{
return obj.GetValue(ItemsSourceProperty) as IEnumerable;
}
public static void SetItemsSource(DependencyObject obj, IEnumerable value)
{
obj.SetValue(ItemsSourceProperty, value);
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.RegisterAttached("ItemsSource", typeof(IEnumerable),
typeof(BindableFlyout), new PropertyMetadata(null, ItemsSourceChanged));
private static void ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ Setup(d as Windows.UI.Xaml.Controls.Flyout); }
#endregion
#region ItemTemplate
public static DataTemplate GetItemTemplate(DependencyObject obj)
{
return (DataTemplate)obj.GetValue(ItemTemplateProperty);
}
public static void SetItemTemplate(DependencyObject obj, DataTemplate value)
{
obj.SetValue(ItemTemplateProperty, value);
}
public static readonly DependencyProperty ItemTemplateProperty =
DependencyProperty.RegisterAttached("ItemTemplate", typeof(DataTemplate),
typeof(BindableFlyout), new PropertyMetadata(null, ItemsTemplateChanged));
private static void ItemsTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ Setup(d as Windows.UI.Xaml.Controls.Flyout); }
#endregion
private static async void Setup(Windows.UI.Xaml.Controls.Flyout m)
{
if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
return;
var s = GetItemsSource(m);
if (s == null)
return;
var t = GetItemTemplate(m);
if (t == null)
return;
var c = new Windows.UI.Xaml.Controls.ItemsControl
{
ItemsSource = s,
ItemTemplate = t,
};
var n = Windows.UI.Core.CoreDispatcherPriority.Normal;
Windows.UI.Core.DispatchedHandler h = () => m.Content = c;
await m.Dispatcher.RunAsync(n, h);
}
}
I got it here: http://blog.jerrynixon.com/2013/12/xaml-how-to-add-itemssource-to-windows.html
I finally got this. To bind to the command on the viewmodel from within the datatemplate, I had to use the following:
<MenuFlyoutItem Text="{Binding CompanyName}"
Command="{Binding CompaniesListViewModel.CompanyListCommand, Source={StaticResource Locator}}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
Locator refers to the ViewmodelLocator. (Note: I am using MVVMLight.)