I am doing a little pet project in WPF to which I am quite new.
My (partial) goal as it follows:
- Open main window, which contains two Comboboxes labeled System and Documents
- Upon loading this window I connect to an .mdb file that contains a table with System and Document columns.
- It creates an ObservableCollection of all the distinct System names stored in the database file and stores them as an arrayList to which my "System" combobox is bound. It successfully fills up the combobox and chooses the first member of the list as a selected item.
- The selectedItem of the "System" combobow is OneWayToSource bound to a string called SystemFilter. Anytime I changed the selection this string is succesfully updated.
- Using this SystemFilter I manage to filter the documents and get the correlating list of titles that is stored in the TitleList observable collection and fills up correctly the "Document" combobox.
It works properly, however everytime I filter the database I create a connection with the file, filter the content extract it and close the connection. Here, in order to avoid opening this connection everytime, I decided to load in all the items in one ObservableCollection called DocumentList and I intend to run LINQ queries on it. and the results of the query i store in Lists that I bind to the combobox. PROBLEM: However in this case the Combobox itemlist does not want to UPDATE Automatically when I choose another system. What can be the reason for this?
/Note: I applied INotifyPropertyChanged in my BaseViewModel and I use FodyWeaver to weave my assembly)
Original working version:
Two Combobox:
<!--System--> <TextBlock Margin="5 0 0 0" Text="System" FontWeight="Bold" HorizontalAlignment="Left"/> <ComboBox SelectionChanged="Combobox_Doc_Sys_SelectionChanged" x:Name="Combobox_Doc_Sys" ItemsSource="{Binding SystemList}" SelectedItem="{Binding SystemFilter,Mode=OneWayToSource}" SelectedIndex="{Binding SystemIndex, Mode=TwoWay}" Padding="2" Margin="5 0 5 0" > </ComboBox> <!--Document--> <TextBlock Margin="5 10 0 0" Text="Document" FontWeight="Bold" HorizontalAlignment="Left"/> <ComboBox x:Name="Combobox_Doc_Doc" SelectionChanged="Combobox_Doc_Doc_SelectionChanged" ItemsSource="{Binding TitleList}" SelectedItem="{Binding TitleFilter, Mode=OneWayToSource}" Padding="2" Margin="5 0 5 0" SelectedIndex="0"> </ComboBox>
Code-behind of MainWindow
public MainWindow() { InitializeComponent(); //Create ViewModel correalating to mainwindow this.DataContext = new MainWindowViewModel(); } /// <summary> /// Event correlating the change of the selected item in Document section's System combobox ///// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Combobox_Doc_Sys_SelectionChanged(object sender, SelectionChangedEventArgs e) { //Call ViewModel's function to filter documentlist based on the Selected system MainWindowViewModel.GetListOfTitle(); //MainWindowViewModel.GetListOfTitle2(); // Restores the selection to the first item in Document section's Document combobox Combobox_Doc_Doc.SelectedIndex = 0; }
GetListOfTitle() function with connection to the .mdb file:
public static void GetListOfTitle() { //List that will store the list of the title //filtering SQL string sysFilterSQL = $"SELECT * FROM DocList WHERE System='{SystemFilter}'"; //Clear List for safety sake TitleList.Clear(); using (OleDbConnection MyConnection = new OleDbConnection(ConnectStringDocList)) { OleDbCommand command = new OleDbCommand(sysFilterSQL, MyConnection); command.Connection = MyConnection; MyConnection.Open(); OleDbDataReader reader = command.ExecuteReader(); //We fill up TitleList with the list of the titles filtered by "system" while (reader.Read()) { var item = reader.GetString(2); TitleList.Add(item); } //Close reader reader.Close(); //Close connection MyConnection.Close(); } }
Parameters
public static ObservableCollection<string> TitleList { get; set; } = new ObservableCollection<string>();
public static string SystemFilter { get; set; } = String.Empty;
When I change to the new version where first I successfully fill up DocumentList with the documents. The GetListofTitle2 method:
internal static void GetListOfTitle2()
{
TitleList = (from s in DocumentList where s.System == $"{SystemFilter}" select s.Title).ToList();
}
With:
public static ObservableCollection<DocumentModel> DocumentList { get; set; } = new ObservableCollection<DocumentModel>();
//--------------------------------------------------------------------------------------------//
public static string SystemFilter { get; set; } = String.Empty;
//--------------------------------------------------------------------------------------------//
public static List<string> TitleList { get; set; } = new List<string>();
In this new version the TitleList is again updated correctly but it doesn't update on the interface :/ What is the issue? I would like to solve it because this solution seems cleaner than everytime open connection and load in the .mdb file
Thanks for the answers in advance
UPDATE: If I modify the second version to still use observableCollections and modify GetListofTitle2 as it follows:
public static void GetListOfTitle2()
{
TitleList =new ObservableCollection<string>((from s in DocumentList where s.System == $"{SystemFilter}" select s.Title).ToList());
}
It still does not update the combobox even though TitleList contains the correct items.