How to properly set itemsources of different control in MVVM pattern ?

don bradman 621 Reputation points
2022-05-13T01:23:01.62+00:00

I have a SQLite database table with multiple columns.

201566-image.png

I want my app to use the unique values from the Party column from the database as the ITEMSOURCE for the combobox on app load and also the datagrid should show the data from the database. Further when I select an item from the combobox the datagrid should filter using the combobox text.

How can I do this using the MVVM pattern ?

Project structure:

201606-image.png

MainWindow.xaml

<Window x:Class="MultiWindowMVVM.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:MultiWindowMVVM"  
        mc:Ignorable="d"  
        Title="MainWindow" Height="450" Width="800">  
	<Window.Resources>  
		<local:DateTimeConverter  
			x:Key="converter" />  
	</Window.Resources>  
	<Border  
		Background="{DynamicResource Darkish}"  
		Margin="0,0,0,0"  
		Padding="0,0,0,0"  
		HorizontalAlignment="Center"  
		VerticalAlignment="Stretch"  
		Width="{Binding ElementName=grid, Path=ActualWidth}">  
		<Grid>  
			<Grid.RowDefinitions>  
				<RowDefinition  
					Height="60" />  
				<RowDefinition  
					Height="Auto" />  
				<RowDefinition  
					Height="Auto" />  
				<RowDefinition  
					Height="*" />  
			</Grid.RowDefinitions>  
			<StackPanel>  
				  
				<ComboBox  ItemsSource="{Binding MyItems}" SelectedItem="{Binding MySelectedItem}"  
				          VerticalAlignment="Top"  
				          HorizontalAlignment="Left"  
				          Width="400"  
				          Height="30"  
				          IsTextSearchEnabled="False"  
				          IsEditable="True"  
				          FontSize="17"  
				          Margin="2,10,30,10"  
				          x:Name="cmb" />  
			</StackPanel>  
			  
			<DockPanel  
				Grid.Row="3"  
				Margin="5,0,5,20">  
				<DataGrid  
					Language="en-IN"  
					BorderBrush="Transparent"  
					VerticalAlignment="Stretch"  
					HorizontalAlignment="Stretch"  
					Background="#212121"  
					RowBackground="#212121"  
					AlternatingRowBackground="#000000"  
					ScrollViewer.CanContentScroll="True"  
					Foreground="White"  
					HeadersVisibility="Column"  
					GridLinesVisibility="None"  
					SelectionMode="Single"  
					IsReadOnly="True"  
					HorizontalScrollBarVisibility="Auto"  
					CanUserAddRows="False"  
					SelectionUnit="FullRow"  
					x:Name="dg"  
					Margin="10,0,10,20"  
					Padding="5"  
					AutoGenerateColumns="False">  
					<DataGrid.Resources>  
						<Style  
							BasedOn="{StaticResource {x:Type DataGridColumnHeader}}"  
							TargetType="{x:Type DataGridColumnHeader}">  
							<Setter  
								Property="Background"  
								Value="#AA00FF" />  
							<Setter  
								Property="FontSize"  
								Value="15" />  
							<Setter  
								Property="FontWeight"  
								Value="DemiBold" />  
						</Style>  
						<Style  
							TargetType="{x:Type DataGrid}">  
							<Setter  
								Property="ColumnWidth"  
								Value="*"></Setter>  
							<Setter  
								Property="FontSize"  
								Value="13"></Setter>  
						</Style>  
						<!--Selected row color-->  
						<Style  
							TargetType="{x:Type DataGridCell}">  
							<Style.Triggers>  
								<Trigger  
									Property="DataGridCell.IsSelected"  
									Value="True">  
									<Setter  
										Property="Background"  
										Value="#7CBA52" />  
									<Setter  
										Property="Foreground"  
										Value="#601BD1" />  
									<Setter  
										Property="FontWeight"  
										Value="DemiBold" />  
								</Trigger>  
								<Trigger  
									Property="IsSelected"  
									Value="True">  
									<Setter  
										Property="BorderThickness"  
										Value="0" />  
								</Trigger>  
							</Style.Triggers>  
						</Style>  
					</DataGrid.Resources>  
					<DataGrid.Columns>  
						<DataGridTextColumn  
							Header="Party"  
							Binding="{Binding Path=Party, Mode=OneWay}"  
							Width="275"  
							IsReadOnly="True" />  
						<DataGridTextColumn  
							Header="Bill No."  
							Binding="{Binding Path=BillNo, Mode=OneWay}"  
							Width="275"  
							IsReadOnly="True" />  
						<DataGridTextColumn  
							Header="Bill Date"  
							Binding="{Binding Path=BillDt, Converter={StaticResource converter}, StringFormat=dd-MM-yyyy, Mode=OneWay}"  
							Width="75"  
							IsReadOnly="True" />  
						<DataGridTextColumn  
							Header="Amount"  
							Binding="{Binding Path=Amt, StringFormat=N2, Mode=OneWay}"  
							Width="75"  
							IsReadOnly="True" />  
						<DataGridTextColumn  
							Header="Due Date"  
							Binding="{Binding Path=DueDt, Converter={StaticResource converter}, StringFormat=dd-MM-yyyy, Mode=OneWay}"  
							Width="75"  
							IsReadOnly="True" />  
						<DataGridTextColumn  
							Header="Paid On"  
							Binding="{Binding Path=PaidOn, Mode=OneWay}"  
							Width="75"  
							IsReadOnly="True" />  
					</DataGrid.Columns>  
					<!--<DataGrid.ContextMenu>  
                        <ContextMenu>  
                            <ContextMenu.Resources>  
                                <Style  
														TargetType="{x:Type MenuItem}">  
                                    <Setter  
															Property="Template">  
                                        <Setter.Value>  
                                            <ControlTemplate  
																	TargetType="{x:Type MenuItem}">  
                                                <Border  
																		Background="{TemplateBinding Background}">  
                                                    <ContentPresenter  
																			Content="{TemplateBinding Header}"  
																			Margin="35 5 10 5" />  
                                                </Border>  
                                                <ControlTemplate.Triggers>  
                                                    <Trigger  
																			Property="IsHighlighted"  
																			Value="True">  
                                                        <Setter  
																				Property="Background"  
																				Value="#5E35B1" />  
                                                    </Trigger>  
                                                </ControlTemplate.Triggers>  
                                            </ControlTemplate>  
                                        </Setter.Value>  
                                    </Setter>  
                                </Style>  
                            </ContextMenu.Resources>  
                            <MenuItem  
													Command="{Binding ShowAddWindow}"  
													Header="Add New Record" />  
                            <Separator />  
                            <MenuItem  
													Command="{Binding ShowEditWindow}"  
													Header="Edit Selected Record" />  
                            <MenuItem  
													Command="{Binding DeleteCommand}"  
													Header="Delete Selected Record" />  
                        </ContextMenu>  
                    </DataGrid.ContextMenu>-->  
				</DataGrid>  
			</DockPanel>  
		</Grid>  
	</Border>  
</Window>  

MainWindow.xaml.cs

using MultiWindowMVVM.ViewModel;  
using System;  
using System.Collections.Generic;  
using System.Globalization;  
using System.Windows;  
using System.Windows.Data;  
  
namespace MultiWindowMVVM  
{  
    [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 MainWindow : Window  
    {  
  
		public MainWindow()  
        {  
            InitializeComponent();  
  
			DataContext = new BillsViewModel();  
  
		}  
    }  
}  

Bills.cs

using System.Collections.ObjectModel;  
using MultiWindowMVVM.ViewModel;  
  
namespace MultiWindowMVVM.Model  
{  
    public class Bills : ViewModelBase  
    {  
		private int _id;  
		public int Id  
		{  
			get  
			{  
				return _id;  
			}  
			set  
			{  
				_id = value;  
				OnPropertyChanged("Id");  
			}  
		}  
  
		private string _party;  
		public string Party  
		{  
			get  
			{  
				return _party;  
			}  
			set  
			{  
				_party = value;  
				OnPropertyChanged("Party");  
			}  
		}  
  
		private string _billNo;  
		public string BillNo  
		{  
			get  
			{  
				return _billNo;  
			}  
			set  
			{  
				_billNo = value;  
				OnPropertyChanged("BillNo");  
			}  
		}  
  
  
		private string _billDt;  
		public string BillDt  
		{  
			get  
			{  
				return _billDt;  
			}  
			set  
			{  
				_billDt = value;  
				OnPropertyChanged("BillDt");  
			}  
		}  
  
		private float _amt;  
		public float Amt  
		{  
			get  
			{  
				return _amt;  
			}  
			set  
			{  
				_amt = value;  
				OnPropertyChanged("Amt");  
			}  
		}  
  
		private string _dueDt;  
		public string DueDt  
		{  
			get  
			{  
				return _dueDt;  
			}  
			set  
			{  
				_dueDt = value;  
				OnPropertyChanged("DueDt");  
			}  
		}  
  
		private string _paidOn;  
		public string PaidOn  
		{  
			get  
			{  
				return _paidOn;  
			}  
			set  
			{  
				_paidOn = value;  
				OnPropertyChanged("PaidOn");  
			}  
		}  
  
		private ObservableCollection<Bills> _bill;  
		public ObservableCollection<Bills> Bill  
		{  
			get  
			{  
				return _bill;  
			}  
			set  
			{  
				_bill = value;  
				OnPropertyChanged("Bill");  
			}  
		}  
	}  
}  

ViewModelBase.cs

using System.ComponentModel;  
  
namespace MultiWindowMVVM.ViewModel  
{  
    public class ViewModelBase : INotifyPropertyChanged  
    {  
		public event PropertyChangedEventHandler PropertyChanged;  
  
		protected void OnPropertyChanged(string propertyName)  
		{  
			if (PropertyChanged != null)  
			{  
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));  
			}  
		}  
	}  
}  

BillsViewModel.cs

using MultiWindowMVVM.Model;  
using System.Collections.Generic;  
using System.Collections.ObjectModel;  
using System.Data.SQLite;  
using System.IO;  
  
namespace MultiWindowMVVM.ViewModel  
{  
    public class BillsViewModel : ViewModelBase  
    {  
  
        public void FillCombos()  
        {  
  
            using (SQLiteConnection conn = new SQLiteConnection(@"Data Source=Bills.db"))  
            {  
                conn.Open();  
  
                string stm = "SELECT DISTINCT Party FROM billdata ORDER BY Party";  
  
                using (SQLiteCommand cmd = new SQLiteCommand(stm, conn))  
                {  
                    using (SQLiteDataReader rdr = cmd.ExecuteReader())  
                    {  
                        while (rdr.Read())  
                        {  
                            MyItems.Add(rdr["Party"].ToString());  
                        }  
                    }  
                }  
  
                conn.Close();  
            }  
  
        }  
  
        public List<string> MyItems { get; set; }  
  
        private string _mySelectedItem;  
		public string MySelectedItem  
		{  
			get { return _mySelectedItem; }  
			set  
			{  
                FillCombos();  
                _mySelectedItem = value;  
            }  
		}  
  
		public BillsViewModel()  
		{  
			var bills = new Bills();  
              
        }  
	}  
}  
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,667 questions
SQL Server
SQL Server
A family of Microsoft relational database management and analysis systems for e-commerce, line-of-business, and data warehousing solutions.
12,642 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,199 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Hui Liu-MSFT 38,026 Reputation points Microsoft Vendor
    2022-05-20T09:50:44.817+00:00

    You could refer to the code below.

    Search for System.Data.SQLite in Manage NuGet Packages .

    App.config:

    <configuration>  
        <startup>   
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />  
        </startup>  
    </configuration>  
    

    MainWindow.xaml:

      <Window.Resources>  
            <local:DateTimeConverter x:Key="converter"/>  
            <local:DecimalConverter x:Key="decimalConverter"/>  
            <local:SelectedItemToItemsSource x:Key="SelectedItemToItemsSource"/>  
            <DataTemplate x:Key="UserGrid">  
                <Border Background="Chocolate" BorderBrush="Black" BorderThickness="1" CornerRadius="5" >  
                    <Grid Margin="10">  
                        <Grid.RowDefinitions>  
                            <RowDefinition/>  
                            <RowDefinition/>  
                            <RowDefinition/>  
                            <RowDefinition/>  
                            <RowDefinition/>  
                            <RowDefinition/>  
                            <RowDefinition/>  
                            <RowDefinition/>  
                            <RowDefinition/>  
                            <RowDefinition/>  
                            <RowDefinition/>  
                        </Grid.RowDefinitions>  
                        <Grid.ColumnDefinitions>  
                            <ColumnDefinition/>  
                            <ColumnDefinition/>  
                        </Grid.ColumnDefinitions>  
                        <TextBlock Text=" Id" Grid.Row="1" Grid.Column="0"/>  
                        <TextBlock Text="Party" Grid.Row="2" Grid.Column="0"/>  
                        <TextBlock Text="BillNo" Grid.Row="3" Grid.Column="0"/>  
                        <TextBlock Text="BillDt" Grid.Row="4" Grid.Column="0"/>  
                        <TextBlock Text="Amt" Grid.Row="5" Grid.Column="0"/>  
                        <TextBlock Text="DueDt" Grid.Row="6" Grid.Column="0"/>  
                        <TextBlock Text="PaidOn" Grid.Row="7" Grid.Column="0"/>  
                        <TextBox Text="{Binding Id, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="1"/>  
                        <TextBox Text="{Binding Party, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="2"/>  
                        <TextBox Text="{Binding BillNo, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="3"/>  
                        <TextBox Text="{Binding BillDt, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="4"/>  
                        <TextBox Text="{Binding Amt, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="5"/>  
                        <TextBox Text="{Binding DueDt, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="6"/>  
                        <TextBox Text="{Binding PaidOn, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="7"/>  
                        <StackPanel Orientation="Horizontal" Grid.Row="10" Grid.ColumnSpan="2" HorizontalAlignment="Right" Margin="5,5,5,5">  
                            <Button Foreground="White" Background="Green" Content="Cancel" Command="{Binding DataContext.CancelCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="4,0"/>  
                            <Button Foreground="White" Background="Green" Content="Delete" Command="{Binding DataContext.DeleteUserCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="4,0"/>  
                            <Button Foreground="White" Background="Green" Content="Save" Command="{Binding DataContext.SaveCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="4,0"/>  
                            <Button Foreground="White" Background="Green" Content="Add" Command="{Binding DataContext.AddCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="4,0"/>  
                        </StackPanel>  
                    </Grid>  
                </Border>  
            </DataTemplate>  
        </Window.Resources>  
        <Grid Margin="0,0,0,-1">  
            <Grid.ColumnDefinitions>  
                <ColumnDefinition Width="7*"/>  
                <ColumnDefinition Width="3*"/>  
            </Grid.ColumnDefinitions>  
            <GroupBox Header="Employee Data" HorizontalAlignment="Center" VerticalAlignment="Center" Height="383" Margin="5,5,5,5">  
                <Grid>  
                    <Grid.RowDefinitions>  
                        <RowDefinition />  
                        <RowDefinition Height="Auto"/>  
                    </Grid.RowDefinitions>  
                    <DataGrid x:Name="dg1" ItemsSource="{Binding Employee}" SelectedItem="{Binding SelectedEmployee}" CanUserAddRows="False"    
                                  CanUserDeleteRows="False" SelectionMode="Single" SelectedIndex="{Binding SelectedIndex}" VerticalAlignment="Top"   
                                  AutoGenerateColumns="False" Margin="5,5,5,5">  
                        <DataGrid.Columns>  
                            <DataGridTextColumn   Header="Party"  Binding="{Binding Path=Party, Mode=TwoWay}"  Width="105"   IsReadOnly="True" />  
                            <DataGridTextColumn  Header="Bill No."  Binding="{Binding Path=BillNo, Mode=TwoWay}"  Width="75"  IsReadOnly="True" />  
    
                            <DataGridTextColumn   Header="Bill Date"   Binding="{Binding Path=BillDt, StringFormat=d, Mode=TwoWay}"  Width="75"  IsReadOnly="True" />  
                            <DataGridTextColumn Header="Amount" Width="75" Binding="{Binding Amt , Converter={StaticResource decimalConverter},StringFormat=N2}"></DataGridTextColumn>  
                            <DataGridTextColumn  Header="Due Date"  Binding="{Binding Path=DueDt, StringFormat=d, Mode=TwoWay}"  Width="75"  IsReadOnly="True" />  
                            <DataGridTextColumn Header="Paid On"  Binding="{Binding Path=PaidOn, Mode=TwoWay}"  Width="75"  IsReadOnly="True" />  
                        </DataGrid.Columns>  
                    </DataGrid>  
                </Grid>  
            </GroupBox>  
            <ItemsControl BindingGroup="{Binding UpdateBindingGroup, Mode=OneWay}"  VerticalAlignment="Top" Margin="5,5,5,5" Grid.Column="1"  
                          ItemTemplate="{StaticResource UserGrid}"  ItemsSource="{Binding SelectedEmployee, Converter={StaticResource SelectedItemToItemsSource}}"    />  
    
        </Grid>  
    

    MainWindow.xaml.cs:

    using System;  
    using System.Collections.Generic;  
    using System.Collections.ObjectModel;  
    using System.ComponentModel;  
    using System.Data;  
    using System.Data.SQLite;  
    using System.Globalization;  
    using System.Windows;  
    using System.Windows.Data;  
    using System.Windows.Input;  
    using System.Windows.Threading;  
    namespace SqliteCrudDemo  
    {  
      /// <summary>  
      /// Interaction logic for MainWindow.xaml  
      /// </summary>  
      public partial class MainWindow : Window  
      {  
        public MainWindow()  
        {  
    
          InitializeComponent();  
          DatabaseLayer.LoadData();  
          this.DataContext = new ViewModelUser();  
        }  
      }  
      public class ViewModelUser : ViewModelBase  
      {  
    
        public ViewModelUser()  
        {  
          personnel = new PersonnelBusinessObject();  
          personnel.EmployeeChanged += new EventHandler(personnel_EmployeeChanged);  
          UpdateBindingGroup = new BindingGroup { Name = "Group1" };  
          CancelCommand = new RelayCommand(DoCancel);  
          SaveCommand = new RelayCommand(DoSave);  
          AddCommand = new RelayCommand(AddUser);  
          DeleteUserCommand = new RelayCommand(DeleteUser);  
        }  
        PersonnelBusinessObject personnel;  
        private ObservableCollection<MData> _Employee;  
        public ObservableCollection<MData> Employee  
        {  
          get  
          {  
            _Employee = new ObservableCollection<MData>(personnel.GetEmployees());  
            return _Employee;  
          }  
        }  
        public int SelectedIndex { get; set; }  
        object _SelectedEmployee;  
        public object SelectedEmployee  
        {  
          get  
          {  
            return _SelectedEmployee;  
          }  
          set  
          {  
            if (_SelectedEmployee != value)  
            {  
              _SelectedEmployee = value;  
              OnPropertyChanged("SelectedEmployee");  
            }  
          }  
        }  
        private BindingGroup _UpdateBindingGroup;  
        public BindingGroup UpdateBindingGroup  
        {  
          get  
          {  
            return _UpdateBindingGroup;  
          }  
          set  
          {  
            if (_UpdateBindingGroup != value)  
            {  
              _UpdateBindingGroup = value;  
              OnPropertyChanged("UpdateBindingGroup");  
            }  
          }  
        }  
        void personnel_EmployeeChanged(object sender, EventArgs e)  
        {  
          Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>  
          {  
            OnPropertyChanged("Employee");  
          }));  
        }  
        public RelayCommand CancelCommand { get; set; }  
        public RelayCommand SaveCommand { get; set; }  
        public RelayCommand AddCommand { get; set; }  
        public RelayCommand DeleteUserCommand { get; set; }  
    
        void DoCancel(object param)  
        {  
          UpdateBindingGroup.CancelEdit();  
          if (SelectedIndex == -1)    //This only closes if new - just to show you how CancelEdit returns old values to bindings  
            SelectedEmployee = null;  
        }  
    
        void DoSave(object param)  
        {  
          UpdateBindingGroup.CommitEdit();  
          var employee = SelectedEmployee as MData;  
          if (SelectedIndex == -1)  
          {  
            personnel.AddEmployee(employee);  
            OnPropertyChanged("Employee"); // Update the list from the data source  
          }  
          else  
            personnel.UpdateEmployee(employee);  
    
          SelectedEmployee = null;  
        }  
    
        void AddUser(object param)  
        {  
    
    
          SelectedEmployee = null; // Unselects last selection. Essential, as assignment below won't clear other control's SelectedItems  
          var employee = new MData();  
          SelectedEmployee = employee;  
        }  
    
        void DeleteUser(object parameter)  
        {  
          var employee = SelectedEmployee as MData;  
          if (SelectedIndex != -1)  
          {  
            personnel.DeleteEmployee(employee);  
            OnPropertyChanged("Employee"); // Update the list from the data source  
          }  
          else  
            SelectedEmployee = null; // Simply discard the new object  
        }  
      }  
    
      public static class DatabaseLayer  
      {  
    
        public static void LoadData()  
        {  
          SQLiteConnection.CreateFile("MyDatabase.sqlite");  
          SQLiteConnection m_dbConnection = new SQLiteConnection("Data Source=MyDatabase.sqlite");  
          m_dbConnection.Open();  
          string sql = "create table MyData (Id INTEGER PRIMARY KEY AUTOINCREMENT, Party varchar(20), BillNo varchar(20), BillDt varchar(20) ,Amt varchar(20) ,DueDt varchar(20),PaidOn varchar(20)) ";  
          SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);  
          command.ExecuteNonQuery();  
          sql = "INSERT INTO MyData(Party,BillNo, BillDt,Amt,DueDt,PaidOn) VALUES('Aakar Medicos1', 'AM-1877','05-01-2022','3324','26-02-2022','22-02-2022')";  
    
    
          command = new SQLiteCommand(sql, m_dbConnection);  
    
          command.ExecuteNonQuery();  
          sql = "INSERT INTO MyData(Party,BillNo, BillDt,Amt,DueDt,PaidOn) VALUES('Aakar Medicos2', 'AM-1877','05-01-2022','3324','26-02-2022','22-02-2022')";  
          command = new SQLiteCommand(sql, m_dbConnection);  
    
          command.ExecuteNonQuery();  
          m_dbConnection.Close();  
        }  
        public static List<MData> GetEmployeeFromDatabase()  
        {  
          try  
          {  
            SQLiteConnection m_dbConnection = new SQLiteConnection("Data Source=MyDatabase.sqlite");  
            SQLiteCommand sqlCom = new SQLiteCommand("Select * From MyData", m_dbConnection);  
            SQLiteDataAdapter sda = new SQLiteDataAdapter(sqlCom);  
            DataTable dt = new DataTable();  
            sda.Fill(dt);  
            var Employee = new List<MData>();  
            foreach (DataRow row in dt.Rows)  
            {  
              var obj = new MData()  
              {  
                Id = Convert.ToInt32(row["Id"]),  
                Party = (string)row["Party"],  
                BillNo = (string)row["BillNo"],  
                BillDt = (string)(row["BillDt"]),  
                Amt = (string)row["Amt"],  
                DueDt = (string)(row["DueDt"]),  
                PaidOn = (string)(row["PaidOn"])  
              };  
              Employee.Add(obj);  
              m_dbConnection.Close();  
            }  
            return Employee;  
    
          }  
          catch (Exception ex)  
          {  
            throw ex;  
          }  
        }  
    
        internal static int InsertEmployee(MData employee)  
        {  
          try  
          {  
            const string query = "INSERT INTO MyData(Party,BillNo, BillDt,Amt,DueDt,PaidOn) VALUES(@Party, @BillNo,@BillDt,@Amt,@DueDt,@PaidOn)";  
            var args = new Dictionary<string, object>  
         {  
               {"@Party", employee.Party},  
               {"@BillNo", employee.BillNo},  
               {"@BillDt", employee.BillDt},  
               {"@Amt", employee.Amt},  
               {"@DueDt", employee.DueDt},  
               {"@PaidOn", employee.PaidOn},  
         };  
            return ExecuteWrite(query, args);  
            MessageBox.Show("Data Saved Successfully.");  
          }  
          catch (Exception ex)  
          {  
            throw ex;  
          }  
          finally  
          {  
    
          }  
        }  
    
        internal static int UpdateEmployee(MData employee)  
        {  
          try  
          {  
            const string query = "UPDATE MyData SET Party = @Party, BillNo = @BillNo, BillDt=@BillDt, Amt=@Amt, DueDt=@DueDt , PaidOn=@PaidOn WHERE Id = @Id";  
    
            var args = new Dictionary<string, object>  
        {  
             {"@Id", employee.Id},  
             {"@Party", employee.Party},  
               {"@BillNo", employee.BillNo},  
               {"@BillDt", employee.BillDt},  
               {"@Amt", employee.Amt},  
               {"@DueDt", employee.DueDt},  
               {"@PaidOn", employee.PaidOn},  
        };  
    
            return ExecuteWrite(query, args);  
            MessageBox.Show("Data Updated Successfully.");  
          }  
          catch (Exception ex)  
          {  
            throw ex;  
          }  
          finally  
          {  
    
          }  
        }  
    
        internal static int DeleteEmployee(MData employee)  
        {  
          try  
          {  
            const string query = "Delete from MyData WHERE Id = @id";  
          var args = new Dictionary<string, object>  
            {  
              {"@id", employee.Id}  
            };  
          return ExecuteWrite(query, args);  
          MessageBox.Show("Data Deleted Successfully.");  
        }  
          catch (Exception ex)  
          {  
            throw ex;  
          }  
          finally  
          {  
    
          }  
        }  
        private static int ExecuteWrite(string query, Dictionary<string, object> args)  
        {  
          int numberOfRowsAffected;  
    
          using (var con = new SQLiteConnection("Data Source=MyDatabase.sqlite"))  
          {  
            con.Open();  
            using (var cmd = new SQLiteCommand(query, con))  
            {  
              foreach (var pair in args)  
              {  
                cmd.Parameters.AddWithValue(pair.Key, pair.Value);  
              }  
              numberOfRowsAffected = cmd.ExecuteNonQuery();  
            }  
            return numberOfRowsAffected;  
          }  
        }  
      }  
    
    
      public class PersonnelBusinessObject  
      {  
        internal EventHandler EmployeeChanged;  
    
        List<MData> Employee { get; set; }  
        public PersonnelBusinessObject()  
        {  
          Employee = DatabaseLayer.GetEmployeeFromDatabase();  
        }  
    
        public List<MData> GetEmployees()  
        {  
          return Employee = DatabaseLayer.GetEmployeeFromDatabase();  
        }  
    
        //public List<NationalityCollection> NationalityCollection { get; set; }  
    
    
        //public List<NationalityCollection> GetNationality()  
        //{  
        //  return NationalityCollection = DatabaseLayer.GetNationality();  
        //}  
        public void AddEmployee(MData employee)  
        {  
          DatabaseLayer.InsertEmployee(employee);  
          OnEmployeeChanged();  
        }  
    
        public void UpdateEmployee(MData employee)  
        {  
          DatabaseLayer.UpdateEmployee(employee);  
          OnEmployeeChanged();  
        }  
    
        public void DeleteEmployee(MData employee)  
        {  
          DatabaseLayer.DeleteEmployee(employee);  
          OnEmployeeChanged();  
        }  
    
        void OnEmployeeChanged()  
        {  
          if (EmployeeChanged != null)  
            EmployeeChanged(this, null);  
        }  
      }  
    
      public class MData : ViewModelBase  
      {  
        private int id;  
        private string party;  
        private string billNo;  
        private string billDt;  
        private string amt;  
        private string dueDt;  
        private string paidOn;  
    
        public MData()  
        {  
        }  
    
        public int Id  
        {  
          get { return id; }  
          set  
          {  
            id = value;  
            OnPropertyChanged("ID");  
          }  
        }  
        public string Party  
        {  
          get { return party; }  
          set  
          {  
            party = value;  
            OnPropertyChanged("Party");  
          }  
        }  
        public string BillNo  
        {  
          get { return billNo; }  
          set  
          {  
            billNo = value;  
            OnPropertyChanged("BillNo");  
          }  
        }  
        public string BillDt  
        {  
          get { return billDt; }  
          set  
          {  
            billDt = value;  
            OnPropertyChanged("BillDt");  
          }  
        }  
        public string Amt  
        {  
          get { return amt; }  
          set  
          {  
            amt = value;  
            OnPropertyChanged("Amt");  
          }  
        }  
    
        public string DueDt  
        {  
          get { return dueDt; }  
          set  
          {  
            dueDt = value;  
            OnPropertyChanged("DueDt");  
          }  
        }  
    
        public string PaidOn  
        {  
          get { return paidOn; }  
          set  
          {  
            paidOn = value;  
            OnPropertyChanged("PaidOn");  
          }  
        }  
      }  
    
      public class RelayCommand : ICommand  
      {  
    
        readonly Action<object> _execute;  
        readonly Predicate<object> _canExecute;  
    
    
        public RelayCommand(Action<object> execute)  
            : this(execute, null)  
        {  
        }  
    
        public RelayCommand(Action<object> execute, Predicate<object> canExecute)  
        {  
          if (execute == null)  
            throw new ArgumentNullException("execute");  
    
          _execute = execute;  
          _canExecute = canExecute;  
        }  
    
        public bool CanExecute(object parameter)  
        {  
          return _canExecute == null ? true : _canExecute(parameter);  
        }  
    
        public event EventHandler CanExecuteChanged  
        {  
          add { CommandManager.RequerySuggested += value; }  
          remove { CommandManager.RequerySuggested -= value; }  
        }  
    
        public void Execute(object parameter)  
        {  
          _execute(parameter);  
        }  
    
      }  
    
      public class SelectedItemToItemsSource : IValueConverter  
      {  
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
        {  
          if (value == null) return null;  
          return new List<object>() { value };  
        }  
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
        {  
          throw new NotImplementedException();  
        }  
      }  
    
      public class ViewModelBase : INotifyPropertyChanged  
      {  
        internal void OnPropertyChanged(string prop)  
        {  
          if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }  
        }  
        public event PropertyChangedEventHandler PropertyChanged;  
      }  
    
      [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(), "d-M-yyyy", CultureInfo.InvariantCulture);  
        }  
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
        {  
          throw new NotImplementedException();  
        }  
      }  
      [ValueConversion(typeof(double), typeof(String))]  
      public class DecimalConverter : IValueConverter  
      {  
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)  
        {  
          return double.Parse(value.ToString(), CultureInfo.InvariantCulture);  
        }  
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)  
        {  
          throw new NotImplementedException();  
        }  
      }  
    }  
    

    The result:
    203980-33.gif


    If the response is helpful, please click "Accept Answer" and upvote it.
     Note: Please follow the steps in our [documentation][5] to enable e-mail notifications if you want to receive the related email notification for this thread. 

    [5]: https://learn.microsoft.com/en-us/answers/articles/67444/email-notifications.html


  2. Peter Fleischer (former MVP) 19,231 Reputation points
    2022-05-30T05:56:20.837+00:00

    Hi,
    please, correct your BillsViewModel:

      public class BillsViewModel : ViewModelBase
      {
        public void FillCombos()
        {
          using (SQLiteConnection conn = new SQLiteConnection(@"Data Source=Bills.db"))
          {
            conn.Open();
    
            string stm = "SELECT DISTINCT Party FROM billdata ORDER BY Party";
    
            using (SQLiteCommand cmd = new SQLiteCommand(stm, conn))
            {
              using (SQLiteDataReader rdr = cmd.ExecuteReader())
              {
                while (rdr.Read())
                {
                  MyItems.Add(rdr["Party"].ToString());
                }
              }
            }
    
            conn.Close();
          }
        }
    
        public List<string> MyItems { get; set; } = new List<string>(); // <-!!!!!
    
        private string _mySelectedItem;
        public string MySelectedItem
        {
          get { return _mySelectedItem; }
          set { _mySelectedItem = value; } // <-!!!!!
        }
    
        public BillsViewModel()
        {
          var bills = new Bills(); // ???
          FillCombos(); // <-!!!!!
        }
      }