I've created a SQLite database Employees.db, added a table tblEmployees and included the database in my project.

The WPF app has a TabControl with multiple TabItem's.
What I'm trying to do is when I launch the app the DataGrid in the first TabItem i.e. filteredGrid should show some filtered data from table tblEmployees and the DataGrid in the second TabItem i.e.dataGrid1 should show all the data and when I click on any of the rows of the DataGrid the textbox's in the second TabItem would get populated with the related column data and when I change any of the data from the textbox's and hit the button then the data should be saved to the database and also immediately reflected on both the DataGrid's on both the TabItem's.
I'm completely new to MVVM pattern and even after reading multiple posts/articles and watching multiple videos regarding how to implement MVVM pattern on the internet I'm still struggling to get a grasp on the subject and can't seem to figure out how to implement it in my simple app.
Anyways, my project structure looks like this
Window1.xaml
<Window x:Class="SQLiteMVVM.View.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SQLiteMVVM.View"
Title="SQLiteMVVM.View" Height="500" Width="800"
WindowState="Maximized">
<Window.Resources>
<local:DateTimeConverter
x:Key="converter" />
<Style
x:Key="myStyle"
TargetType="Button">
<Setter
Property="Foreground"
Value="#B9F6CA" />
<Setter
Property="Background"
Value="#01579B" />
<Style.Triggers>
<Trigger
Property="IsMouseOver"
Value="True">
<Setter
Property="Foreground"
Value="#E65100" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<TabControl>
<TabItem Header="General">
<DataGrid ItemsSource="{Binding employees}"
Margin="15"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Grid.Row="0"
x:Name="filteredGrid"
Width="700"
Height="400"
AutoGenerateColumns="False"
CanUserAddRows="False"
IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Employee Name" Binding="{Binding Path=empname}" IsReadOnly="True"/>
<DataGridTextColumn Header="Age" Binding="{Binding Path=age}" IsReadOnly="True" />
<DataGridTextColumn Header="Date of Birth" Binding="{Binding Path=bdate, Converter={StaticResource converter}, StringFormat=dd-MM-yyyy}" IsReadOnly="True" />
<DataGridTextColumn Header="Salary" Binding="{Binding Path=salary, StringFormat=N2}" IsReadOnly="True" />
<DataGridTextColumn Header="Comments" Binding="{Binding Path=remarks}" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem Header="CRUD">
<Grid>
<Grid.RowDefinitions>
<RowDefinition
Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<DataGrid
Margin="15"
HorizontalAlignment="Left"
Grid.Row="0"
x:Name="dataGrid1"
Width="700"
Height="400"
AutoGenerateColumns="False"
CanUserAddRows="False"
IsReadOnly="True"
SelectionMode="Single"
SelectionUnit="FullRow">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridCell}">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="DoSelectedRow"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn x:Name="col1" Header="Employee Name" Binding="{Binding Path=empname}" IsReadOnly="True"/>
<DataGridTextColumn x:Name="col2" Header="Age" Binding="{Binding Path=age}" IsReadOnly="True" />
<DataGridTextColumn x:Name="col3" Header="Date of Birth" Binding="{Binding Path=bdate, Converter={StaticResource converter}, StringFormat=dd-MM-yyyy}" IsReadOnly="True" />
<DataGridTextColumn x:Name="col4" Header="Salary" Binding="{Binding Path=salary, StringFormat=N2}" IsReadOnly="True" />
<DataGridTextColumn x:Name="col5" Header="Comments" Binding="{Binding Path=remarks}" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
<StackPanel
Grid.Row="1">
<Label x:Name="lblempname"
Content="Name :" />
<TextBox
HorizontalAlignment="Left"
Margin="5"
x:Name="empname"
Height="25"
Width="280" />
<Label x:Name="lblage"
Content="Age :" />
<TextBox
HorizontalAlignment="Left"
Margin="5"
x:Name="age"
Height="25"
Width="200" />
<Label x:Name="lblbdate"
Content="Date of Birth :" />
<TextBox
HorizontalAlignment="Left"
Margin="5"
x:Name="bdate"
Height="25"
Width="80" />
<Label x:Name="lblsalary"
Content="Salary :" />
<TextBox
HorizontalAlignment="Left"
Margin="5"
x:Name="salary"
Height="25"
Width="80" />
<Label x:Name="lblremarks"
Content="Comments :" />
<TextBox
HorizontalAlignment="Left"
Margin="5"
x:Name="remarks"
Height="25"
Width="80" />
<Button
x:Name="update"
Width="55"
Height="25"
Content="Update"
Style="{StaticResource myStyle}" />
</StackPanel>
</Grid>
</TabItem>
<TabItem Header="Details" />
</TabControl>
</Grid>
</Window>
Window1.xaml.cs
using System;
using System.Data;
using System.Data.SQLite;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using SQLiteMVVM.ViewModel;
namespace SQLiteMVVM.View
{
[ValueConversion(typeof(DateTime), typeof(String))]
public class DateTimeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return DateTime.ParseExact(value.ToString(), "yyyy-MM-dd", CultureInfo.InvariantCulture);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
public partial class Window1 : Window
{
EmployeesViewModel co;
public Window1()
{
InitializeComponent();
FillFilterData();
lblempname.Visibility=Visibility.Hidden;
lblage.Visibility=Visibility.Hidden;
lblbdate.Visibility=Visibility.Hidden;
lblsalary.Visibility=Visibility.Hidden;
lblremarks.Visibility=Visibility.Hidden;
empname.Visibility=Visibility.Hidden;
age.Visibility=Visibility.Hidden;
bdate.Visibility=Visibility.Hidden;
salary.Visibility=Visibility.Hidden;
remarks.Visibility=Visibility.Hidden;
update.Visibility=Visibility.Hidden;
co = new EmployeesViewModel();
base.DataContext = co;
}
public void DoSelectedRow(object sender, MouseButtonEventArgs e)
{
DataGridCell cell = sender as DataGridCell;
if (cell != null && !cell.IsEditing)
{
DataGridRow row = FindVisualParent<DataGridRow>(cell);
if (row != null)
{
row.IsSelected = !row.IsSelected;
e.Handled = true;
}
}
}
public static Parent FindVisualParent<Parent>(DependencyObject child) where Parent : DependencyObject
{
DependencyObject parentObject = child;
while (!((parentObject is System.Windows.Media.Visual)
|| (parentObject is System.Windows.Media.Media3D.Visual3D)))
{
if (parentObject is Parent || parentObject == null)
{
return parentObject as Parent;
}
else
{
parentObject = (parentObject as FrameworkContentElement).Parent;
}
}
parentObject = VisualTreeHelper.GetParent(parentObject);
if (parentObject is Parent || parentObject == null)
{
return parentObject as Parent;
}
else
{
return FindVisualParent<Parent>(parentObject);
}
}
public void FillFilterData()
{
using(SQLiteConnection conn= new SQLiteConnection(@"Data Source=C:\Users\Tamal Banerjee\source\repos\WpfMVVM\WpfMVVM\bin\Debug\Employees.db;"))
{
conn.Open();
SQLiteCommand command = new SQLiteCommand("SELECT * FROM tblEmployees WHERE Remarks = ''", conn);
command.ExecuteNonQuery();
SQLiteDataAdapter adap = new SQLiteDataAdapter(command);
DataTable dt = new DataTable("tblEmployees");
adap.Fill(dt);
dataGrid1.ItemsSource=dt.DefaultView;
conn.Close();
}
}
public static string FormattedDate(string init)
{
string[] tempArray = init.Split('-');
string newFormat = tempArray[2].ToString()+"-"+tempArray[1].ToString()+"-"+tempArray[0].ToString();
return newFormat;
}
void dataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
DataGrid grid = (DataGrid)sender;
dynamic selected_row = grid.SelectedItem;
if (selected_row == null)
{
empname.Text = "";
age.Text = "";
bdate.Text = "";
salary.Text = "";
remarks.Text = "";
lblempname.Visibility=Visibility.Hidden;
lblage.Visibility=Visibility.Hidden;
lblbdate.Visibility=Visibility.Hidden;
lblsalary.Visibility=Visibility.Hidden;
lblremarks.Visibility=Visibility.Hidden;
empname.Visibility=Visibility.Hidden;
age.Visibility=Visibility.Hidden;
bdate.Visibility=Visibility.Hidden;
salary.Visibility=Visibility.Hidden;
remarks.Visibility=Visibility.Hidden;
update.Visibility=Visibility.Hidden;
}
else
{
lblempname.Visibility=Visibility.Visible;
lblage.Visibility=Visibility.Visible;
lblbdate.Visibility=Visibility.Visible;
lblsalary.Visibility=Visibility.Visible;
lblremarks.Visibility=Visibility.Visible;
empname.Visibility=Visibility.Visible;
age.Visibility=Visibility.Visible;
bdate.Visibility=Visibility.Visible;
salary.Visibility=Visibility.Visible;
remarks.Visibility=Visibility.Visible;
update.Visibility=Visibility.Visible;
empname.Text = selected_row["col1"].ToString();
age.Text = selected_row["col2"].ToString();
bdate.Text = FormattedDate(selected_row["col3"].ToString());
salary.Text = selected_row["col4"].ToString();
remarks.Text = FormattedDate(selected_row["col5"].ToString());
}
}
}
}
Employees.cs
using System;
namespace SQLiteMVVM.Model
{
public class Employees
{
public string empname { get; set; }
public int age { get; set; }
public string bdate { get; set; }
public float salary { get; set; }
public string remarks { get; set; }
}
}
EmployeesViewModel.cs
using System;
using System.Windows;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Data.SQLite;
using SQLiteMVVM.Model;
namespace SQLiteMVVM.ViewModel
{
public class EmployeesViewModel : INotifyPropertyChanged
{
static String connectionString = @"Data Source=C:\Users\Tamal Banerjee\source\repos\WpfMVVM\WpfMVVM\bin\Debug\Employees.db;";
SQLiteConnection con;
SQLiteCommand cmd;
SQLiteDataAdapter adapter;
DataSet ds;
public ObservableCollection<Employees> employees { get; set; }
public EmployeesViewModel()
{
FillDG();
}
public void FillDG()
{
try
{
con = new SQLiteConnection(connectionString);
con.Open();
cmd = new SQLiteCommand("select * from tblEmployees", con);
adapter = new SQLiteDataAdapter(cmd);
ds = new DataSet();
adapter.Fill(ds, "tblEmployees");
if (employees == null)
employees = new ObservableCollection<Employees>();
foreach (DataRow dr in ds.Tables[0].Rows)
{
employees.Add(new Employees
{
empname = dr[0].ToString(),
age = Convert.ToInt32(dr[1].ToString()),
bdate = dr[2].ToString(),
salary = (float)Convert.ToDecimal(dr[3].ToString()),
remarks = dr[4].ToString(),
});
}
}
catch (Exception ex)
{
MessageBox.Show("Error");
}
finally
{
ds = null;
adapter.Dispose();
con.Close();
con.Dispose();
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
When I run the app the Datagrid in the first tabitem shows all the data instead of filtered data and the Datagrid in the second tabitem shows nothing. Please help!

