How to add content to each SfNavigationItem using MVVM for WPF SfNavigationDrawer
This article describes how to add content to each NavigationItem of SfNavigationDrawer using MVVM.
Step 1: Create a WPF project using the Visual studios’ latest version.
Step 2: Install the SfNavigationDrawer NuGet package from Manage NuGet Packages by right-clicking the Solution Explorer window.
Step 3: Initialize SfNavigationDrawer in XAML and set the properties that need to be displayed in WPF.
Step 4: Create the DelegateCommand class, which must inherit from the ICommand interface.
DelegateCommand
public class DelegateCommand<T> : ICommand { private Predicate<T> _canExecute; private Action<T> _method; bool _canExecuteCache = true; /// <summary> /// Initializes a new instance of the <see cref="DelegateCommand"/> class. /// </summary> /// <param name="method">The method.</param> public DelegateCommand(Action<T> method) : this(method, null) { } /// <summary> /// Initializes a new instance of the <see cref="DelegateCommand"/> class. /// </summary> /// <param name="method">The method.</param> /// <param name="canExecute">The can execute.</param> public DelegateCommand(Action<T> method, Predicate<T> canExecute) { _method = method; _canExecute = canExecute; } /// <summary> /// Defines the method that determines whether the command can execute in its current state. /// </summary> /// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param> /// <returns> /// true if this command can be executed; otherwise, false. /// </returns> public bool CanExecute(object parameter) { if (_canExecute != null) { bool tempCanExecute = _canExecute((T)parameter); if (_canExecuteCache != tempCanExecute) { _canExecuteCache = tempCanExecute; this.RaiseCanExecuteChanged(); } } return _canExecuteCache; } /// <summary> /// Raises CanExecuteChanged event to notify changes in command status. /// </summary> public void RaiseCanExecuteChanged() { if (CanExecuteChanged != null) { CanExecuteChanged(this, new EventArgs()); } } /// <summary> /// Defines the method to be called when the command is invoked. /// </summary> /// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param> public void Execute(object parameter) { if (_method != null) _method.Invoke((T)parameter); } #region ICommand Members /// <summary> /// /// </summary> public event EventHandler CanExecuteChanged; #endregion }
Step 5: Create a separate view for each NavigationItem.
HomeView.Xaml
<UserControl x:Class="NavigationSample.Views.HomeView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:NavigationSample.Views" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <StackPanel Orientation="Vertical"> <TextBox Text="Home" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center" Height="50" Width="100" VerticalAlignment="Center"/> </StackPanel> </UserControl>
BookView.Xaml
<UserControl x:Class="NavigationSample.Views.BooksView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:NavigationSample.Views" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <StackPanel Orientation="Vertical"> <TextBox HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Text="BookView" Height="50" Width="100" VerticalAlignment="Center"/> <Button Margin="0,10,0,0" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Height="50" Width="100" VerticalAlignment="Center" Content="Click"/> </StackPanel> </Grid> </UserControl>
Step 6: Create ViewModel class and declare the properties that need to be assigned.
ViewModel
public class ViewModel : INotifyPropertyChanged { private ContentControl contentControl; private bool _canperformaction = true; public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string name) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(name)); } } public ViewModel(ContentControl content) { contentControl = content; ClickCommand = new DelegateCommand<object>(ClickAction, CanPerformClickAction); } public bool CanPerformAction { get { return _canperformaction; } set { _canperformaction = value; this.ClickCommand.RaiseCanExecuteChanged(); this.OnPropertyChanged("CanPerformAction"); } } private bool CanPerformClickAction(object parameter) { return CanPerformAction; } public DelegateCommand<object> ClickCommand { get; set; } private void ClickAction(object parameter) { if ((string)parameter == "Home") { contentControl.Content = new HomeView(); } else if ((string)parameter == "Books") { contentControl.Content = new BooksView(); } } }
Step 7: Bind the ViewModel property to WPF SfNavigationItem property of Command.
MainWindow.Xaml
<Window x:Class="NavigationSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:NavigationSample" xmlns:sf="http://schemas.syncfusion.com/wpf" xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <sf:SfNavigationDrawer x:Name="navigationDrawer" Grid.Column="0" DisplayMode="Compact"> <sf:SfNavigationDrawer.ContentView> <Grid> <ContentControl x:Name="ActiveItem" HorizontalAlignment="Center" VerticalAlignment="Center" Content="ContentView"/> </Grid> </sf:SfNavigationDrawer.ContentView> <sf:NavigationItem Header="Home" Command="{Binding ClickCommand}" CommandParameter="Home" IsEnabled="True"> <sf:NavigationItem.Icon> <md:PackIcon Width="30" Height="30" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Gray" Kind="Home" /> </sf:NavigationItem.Icon> </sf:NavigationItem> <sf:NavigationItem Header="Books" Command="{Binding ClickCommand}" CommandParameter="Books" IsEnabled="True"> <sf:NavigationItem.Icon> <md:PackIcon Width="30" Height="30" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Gray" Kind="Bookshelf" /> </sf:NavigationItem.Icon> </sf:NavigationItem> <sf:SfNavigationDrawer.FooterItems> <sf:NavigationItem Header="Log Out" SelectionBackground="Transparent"> <sf:NavigationItem.Icon> <md:PackIcon Width="30" Height="30" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Gray" Kind="Power" /> </sf:NavigationItem.Icon> </sf:NavigationItem> </sf:SfNavigationDrawer.FooterItems> </sf:SfNavigationDrawer> </Grid> </Window>
MainWindow.cs
public partial class MainWindow : Window { ViewModel viewModel; public MainWindow() { InitializeComponent(); this.DataContext = new ViewModel(ActiveItem); } }
MainWindow
HomeView
BookView
You can download the sample in this link