question

donbradman-4481 avatar image
0 Votes"
donbradman-4481 asked PeterFleischer-3316 commented

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

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();
                
         }
     }
 }


dotnet-csharpwindows-wpfdotnet-sqlite
image.png (13.9 KiB)
image.png (20.6 KiB)
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi,@donbradman-4481. I'm trying to implement binding Combobox and DataGrid separately, I'll back if there are any updates.

0 Votes 0 ·

Hello, @HuiLiu-MSFT , I don't mind binding Combobox and DataGrid separately as long as it follows MVVM pattern properly and doesn't slow down the app. Also, do note that the datagrid will have menuitems using which data will be added, edited and deleted to the database and datagrid data should update instantly and properly. Further when I add a new data and say its Party column data is new then that should automatically get updated to the itemsource collection of the combobox.

0 Votes 0 ·
HuiLiu-MSFT avatar image
0 Votes"
HuiLiu-MSFT answered HuiLiu-MSFT commented

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 to enable e-mail notifications if you want to receive the related email notification for this thread. 


33.gif (252.5 KiB)
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @HuiLiu-MSFT , thanks for your post, but it did not answer my actual question i.e. getting unique data from a particular database table column and setting it as its itemsource and when an item from that combobox is selected then the datagrid should show filtered data as per the that selected/chosen combobox item.

0 Votes 0 ·

Hi,@donbradman-4481. If you want to implement the functions here in the way of MVVM, please share with me the project code at that time .( create a GitHub repository and provide the link.

https://docs.microsoft.com/en-us/learn/modules/visual-studio-github-push/ )


0 Votes 0 ·
PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered PeterFleischer-3316 commented

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(); // <-!!!!!
     }
   }


· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi,

If I do

 public List<string> MyItems { get; set; }
 MyItems = new List<string>();

instead of

 public List<string> MyItems { get; set; } = new List<string>();

will it be okay as I'm getting Invalid token '=' in class, struct, or interface member declaration (CS1519) error if I do it your way ?

Also. are there any better approaches ?

0 Votes 0 ·

Hi,
it's ok assign initial value in code. See here.


0 Votes 0 ·