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