Reputation: 81
I try to implement the MVVM pattern for this sample (just simple paging part) with Microsoft.Toolkit.Mvvm unfortunately, I failed :( because I'm so noob in WPF also MVVM :))
the primary problem is how can I pass an argument of an event to command with InvokeCommandAction (Microsoft.Xaml.Behaviors.Wpf)? there is limited documentation and wiki I think... in this scenario, I change this code in MainWindow.xaml :
...
<ui:Frame x:Name="ContentFrame" Navigated="ContentFrame_Navigated" />
</ui:NavigationView>
to :
...
<ui:Frame x:Name="ContentFrame" DataContext="{Binding ContentFrameVM}">
<i:Interaction.Triggers>
<!-- Events -->
<i:EventTrigger EventName="Navigated">
<i:InvokeCommandAction Command="{Binding ContentFrame_NavigatedCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ui:Frame>
and move the code related to this event from MainWindow.xaml.cs :
private void ContentFrame_Navigated(object sender, NavigationEventArgs e)
{
if (e.SourcePageType() == typeof(SettingsPage))
{
NavView.SelectedItem = NavView.SettingsItem;
}
else
{
NavView.SelectedItem = NavView.MenuItems.OfType<NavigationViewItem>().FirstOrDefault(x => GetPageType(x) == e.SourcePageType());
}
}
to MainWindowViewModel.cs and change it to :
class MainWindowViewModel : ObservableObject
{
public IRelayCommand ContentFrame_NavigatedCommand { get; }
private NavigationView _navigationViewVM;
public NavigationView NavigationViewVM
{
get => _navigationViewVM;
set => SetProperty(ref _navigationViewVM, value);
}
private ModernWpf.Controls.Frame _contentFrameVM;
public ModernWpf.Controls.Frame ContentFrameVM
{
get => _contentFrameVM;
set => SetProperty(ref _contentFrameVM, value);
}
public MainWindowViewModel()
{
ContentFrame_NavigatedCommand = new RelayCommand<object>(ContentFrame_Navigated, (o) => { return true; });
}
...
private void ContentFrame_Navigated(object o)
{
NavigationEventArgs e = o as NavigationEventArgs;
if (e.SourcePageType() == typeof(Views.Pages.SettingsPage))
{
NavigationViewVM.SelectedItem = NavigationViewVM.SettingsItem;
}
else
{
NavigationViewVM.SelectedItem = NavigationViewVM.MenuItems.OfType<NavigationViewItem>().FirstOrDefault(x => GetPageType(x) == e.SourcePageType());
}
}
or try this :
public MainWindowViewModel()
{
ContentFrame_NavigatedCommand = new RelayCommand<NavigationEventArgs>(ContentFrame_Navigated);
}
...
private void ContentFrame_Navigated(NavigationEventArgs e)
{
...
}
in debug mode "ContentFrame_Navigated" doesn't fire at all and "ContentFrame_NavigatedCommand" just triggered once at startup (in that time "NavigationViewVM" is null!)
I'm ignoring an obvious issue Isn't that so? also, it's a Possible duplicate sorry about that but I tried to read all similar questions and ref for days!
Upvotes: 3
Views: 5425
Reputation: 81
Thanks to Jesse's comment... I edit that part of the code but the main problem was ItemInvoked event was not implemented at all! however, I decide to implement SelectionChanged event instead: MainWindow.xaml :
<ui:NavigationView>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged" SourceObject="{Binding ElementName=NavView}">
<i:InvokeCommandAction Command="{Binding NavVM_SelectionChangedCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
...
in MainWindowViewModel.cs:
private void NavVM_SelectionChanged(NavigationViewSelectionChangedEventArgs args)
{
if (args.IsSettingsSelected)
{
Navigate(typeof(Views.Pages.SettingsPage));
}
else
{
var selectedItem = (NavigationViewItem)args.SelectedItem;
Navigate(selectedItem);
}
}
Upvotes: 4