In most cases, when you develop WPF UI application with the DataGrid control, end-users demand Excel like features with various shortcuts for performing Insert and Delete operations. The WPF DataGrid Context Menu helps us to develop similar kind of UI applications. In the code snippet given below, I have explained the same.
Step 1: Open VS2010 and create a WPF application, name it as
‘WPF4.0_DataGrid_Rows_Management’. In this project add the class file with following classes:
/// <summary>
/// The Entity Class
/// </summary>
public class Employee
{
public int EmpNo { get; set; }
public string EmpName { get; set; }
public int Salary { get; set; }
public string Designation { get; set; }
}
/// <summary>
/// The Model Class
/// </summary>
public class EmployeeCollection : ObservableCollection<Employee>
{
public EmployeeCollection()
{
Add(new Employee() { EmpNo = 101, EmpName = "Yudhistir",
Designation = "KING", Salary = 2000000 });
Add(new Employee() { EmpNo = 102, EmpName = "Bheem",
Designation = "KOSHDHIKARI", Salary = 1500000 });
Add(new Employee() { EmpNo = 103, EmpName = "Arjun",
Designation = "SUPREME COMMANDOR", Salary = 1200000 });
Add(new Employee() { EmpNo = 104, EmpName = "Sahdev",
Designation = "CHIEF COMMANDOR", Salary = 1000000 });
Add(new Employee() { EmpNo = 105, EmpName = "Nakul",
Designation = "CHIEF MEDICAL OFFICER", Salary = 1000000 });
Add(new Employee() { EmpNo = 106, EmpName = "Krishna",
Designation = "CHIEF STRATEGY ADVISOR", Salary = 8000000 });
Add(new Employee() { EmpNo = 107, EmpName = "Dustdyumna",
Designation = "MILITARY CHIEF", Salary = 1000000 });
Add(new Employee() { EmpNo = 108, EmpName = "Abhmanyu",
Designation = "Lt. GENERAL", Salary = 1000000 });
}
}
The above classes define Entity and Collection class for Employee.
Step 2: In the same project, add a new class for performing the DML operations as below:
/// <summary>
/// The Class is used for Data Manipulation
/// </summary>
public class DataOperations
{
EmployeeCollection Employees;
public DataOperations()
{
Employees = new EmployeeCollection();
}
public EmployeeCollection InsertRecord(int Index)
{
Employees.Insert(Index+1, new Employee());
return Employees;
}
public EmployeeCollection DeleteRecord(int Index)
{
Employees.RemoveAt(Index);
return Employees;
}
}
The above class performs Insert and Delete operation on the Employee collection.
Step 3: In the same project, add a Command and ViewModel class. The command class defines command for Performing Insert and Delete command. The command class implements ICommand interface. This command object is bound with the UI for performing operation. The ViewModel class define properties used for DataBinding with UI. The code is as below:
public class ViewModel : INotifyPropertyChanged
{
RelayCommand _InsertCommand, _DeleteCommand;
public RelayCommand DeleteCommand
{
get { return _DeleteCommand; }
set { _DeleteCommand = value; }
}
public RelayCommand InsertCommand
{
get { return _InsertCommand; }
set { _InsertCommand = value; }
}
DataOperations objDML;
public ViewModel()
{
objDML = new DataOperations();
InsertCommand = new RelayCommand(Res =>
Employees= objDML.InsertRecord(RecordIndex));
DeleteCommand = new RelayCommand(Res =>
Employees = objDML.DeleteRecord(RecordIndex));
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string pName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(pName) );
}
}
int _RecordIndex;
public int RecordIndex
{
get { return _RecordIndex; }
set
{
_RecordIndex = value;
OnPropertyChanged("RecordIndex");
}
}
EmployeeCollection _Employees = new EmployeeCollection();
public EmployeeCollection Employees
{
get { return _Employees; }
set
{
_Employees = value;
OnPropertyChanged("Employees");
}
}
}
/// <summary>
/// The Command Class
/// </summary>
public class RelayCommand : ICommand
{
public Action<object> actionToExecute;
public RelayCommand(Action<object> action)
{
actionToExecute = action;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
actionToExecute(parameter);
}
}
Step 4: Open the MainWindow.Xaml and write the following XAML code with DataBinding:
<Window x:Class="WPF4._0_DataGrid_Rows_Management.MainWindow"
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml”
Title="MainWindow" Height="350" Width="742"
xmlns:data="clr-namespace:WPF4._0_DataGrid_Rows_Management">
<Window.Resources>
<data:ViewModel x:Key="EmpVM"></data:ViewModel>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource EmpVM}}">
<DataGrid AutoGenerateColumns="False" Height="287"
HorizontalAlignment="Left" Margin="23,12,0,0"
Name="dgEmp" VerticalAlignment="Top" Width="657"
ItemsSource="{Binding Path=Employees}" ColumnWidth="*"
SelectedIndex="{Binding Path=RecordIndex,Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTextColumn Header="EmpNo" Binding="{Binding EmpNo}" />
<DataGridTextColumn Header="EmpName" Binding="{Binding EmpName}" />
<DataGridTextColumn Header="Salary" Binding="{Binding Salary}" />
<DataGridTextColumn Header="Designation" Binding="{Binding Designation}" />
</DataGrid.Columns>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding InsertCommand}"
CommandParameter="{Binding RecordIndex}" Header="Insert"/>
<MenuItem Command="{Binding DeleteCommand}"
CommandParameter="{Binding RecordIndex}" Header="Delete"/>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
</Grid>
</Window>
The above XAML code defines the Context Menu for Insert and Delete operation. It contains Menu-Item for Insert and Delete. InsertCommand and DeleteCommand are bind with the Command property of the Menu-Item. Since for Insert and Delete operations the Index for the record to be deleted and insert position is required the CommandParameter is bind with the RecordIndex property declared in the ViewModel class.
Step 5: Run the application and right-click on the DataGrid row. You will get a context menu as shown below:
After selecting the ‘Insert’ menu the result will be as below:
A new row is added.
Select any row to be deleted by right clicking on the DataGrid row. The result will be as below: For e.g. I am selecting Record 104 to be deleted
Tweet
3 comments:
Hi,
Can you please show how to pass
EmpNo and EmpName as Command Bindings
in the above example?
Best Implementation Of WPF Extended DataGrid Can be found here
WPF Extended DataGrid
Features
Column Choosers.
AutoFilter Control.
Export To Excel Feature.
Copy Paste To Excel and Copy Paste From Excel To DataGrid.
Three State Sorting.
Displaying Sort Order If Multiple Sort is done.
Export To Excel with formatting.
Export To PDF with formatting.
Hello. I'm still learning about WPF and XAML and this whole binding stuff sometimes is hard for me to achieve.
Anyway. What I don't understand is those lines:
InsertCommand = new RelayCommand(Res => Employees = objDML.InsertRecord(RecordIndex));
DeleteCommand = new RelayCommand(Res => Employees = objDML.DeleteRecord(RecordIndex));
My question is: What's Res?
Because in my understanding it is null since it isn't declared anywhere. And since it is null then why even use this or how to use RelayCommand without passing null value
Post a Comment