public event ChangedGridSizeHandler GridWasChanged; // event when the grid was changed inside the Model class, during Search public Model(IViewGUI FormToModel) { MyTable = new DataTable() { TableName = "TableAsInGrid" }; // initialize internal DataTable for storing the data from the GUI/Form1 class UpdatedTable = new DataTable() { TableName = "TemporaryTableAfterSearch" }; // initialize temporary DataTable for storing intermidiate results after Search ModifiedGridSize = 0; // set the DataGrid size to 0 at the 1st run MyTable.Columns.Add("Title", typeof(string)); // initialize columns for the DataTable MyTable.Columns.Add("Artist", typeof(string)); MyTable.Columns.Add("Album", typeof(string)); MyTable.Columns.Add("Genre", typeof(string)); MyTable.Columns.Add("Year", typeof(string)); MyTable.Columns.Add("FilePath", typeof(string)); // initialize columns for the temporary DataTable UpdatedTable.Columns.Add("Title", typeof(string)); UpdatedTable.Columns.Add("Artist", typeof(string)); UpdatedTable.Columns.Add("Album", typeof(string)); UpdatedTable.Columns.Add("Genre", typeof(string)); UpdatedTable.Columns.Add("Year", typeof(string)); UpdatedTable.Columns.Add("FilePath", typeof(string)); FormToModel.GridWasChangedSignUp(this); // sign up for the event, which occures when the Grid size was changed in Form1 class SearchBoxAfter = ""; searchBox = ""; }
// triggered when Add button is pushed in GUI, after this all available tags are extracted from the audio files private void UserView_AddButtonPushed(IViewGUI sender) // sender is the object of Form1 class, through which we can access public properties { FilePathForController = sender.FilePaths; // receive FilePaths from Form1 via public Property file path which is defined in IView Interface. FileNameForController = sender.FileNames; // receive FileName from Form1 class / GUI for Title, if its abasent int k = 0; // iterator thgough filenames for Title for (int i = 0; i < FilePathForController.Length; i++) { UltraID3 myMp3 = new UltraID3(); // initialize Tag class (external reference) try { myMp3.Read(FilePathForController[i]); // if there is no titles in the Tag then substitute it with file name of the audio file if (myMp3.Title == "") { sender.Title = FileNameForController[k].Substring(0, FileNameForController[k].IndexOf('.')); // extract file name without extension (.mp3) k++; } else { sender.Title = string.Format("{0}", myMp3.Title); // send the extracted tag/Title to the Form1 class } sender.Year = string.Format("{0}", myMp3.Year); // send all tags to the Form1 class via public Properties to the Form1 class sender.Artist = string.Format("{0}", myMp3.Artist); sender.Album = string.Format("{0}", myMp3.Album); sender.Genre = string.Format("{0}", myMp3.Genre); // send all extracted Tags to the Form1 class via 2D array, where it is saved in private fields and where it is send to final DataGrid View sender.TableContr[i] = new string[] { sender.Title, sender.Artist, sender.Album, sender.Genre, sender.Year, sender.FilePaths[i] }; } catch (HundredMilesSoftware.UltraID3Lib.ID3FileException) // Tags are not valid { MessageBox.Show("Reading ID3 Tag from file is wrong"); } } }
private void UserView_FormOpened(IViewGUI sender) { //ReadXMLNewResults(); ReadXMLPreviousResults(); TableFromModel = null; // prepare 2D array for sending results from inner DataTable(with data from XML) to Form's Data Grid TableFromModel = new string[MyTable.Rows.Count][]; // initialize the new size of 2D array with the size of updated DataTable for (int i = 0; i < MyTable.Rows.Count; i++) { TableFromModel[i] = new string[6]; for (int j = 0; j < TableFromModel[i].Length; j++) { TableFromModel[i][j] = MyTable.Rows[i].Field <string>(j); // populate 2D array from inner Data Table (Model Class) } } if (GridWasChanged != null) { GridWasChanged(this); // event triggered if the new Data Table size (and 2D array size too) are different from the previous size sender.TableContr = TableFromModel; // send new data via 2D array to the Form's Data Grid if (TableFromModel == null) // if nothing to send { sender.NewGridSize = 0; // send the new size as 0 if there are no results in Data Table } else { sender.NewGridSize = TableFromModel.Length;// send the new size as well } } }
// method called when the Save button was pushedin GUI private void UserView_SaveButtonPushed(IViewGUI sender) { TableFromModel = sender.TableContr; // receive data from Grid to the private double array (TableFromModel) MyTable.Clear(); //UpdateXMLPreviousResults(); if (TableFromModel != null) { for (int i = 0; i < TableFromModel.GetLength(0); i++) { MyTable.Rows.Add(TableFromModel[i][0], TableFromModel[i][1], TableFromModel[i][2], TableFromModel[i][3], TableFromModel[i][4], TableFromModel[i][5]); //ModifiedGridSize++; } } UpdateXMLPreviousResults(); }
// this method is called when the text in the Search was changed and corresponding event was fired private void UserView_SearchBoxTextChanged(IViewGUI sender) { SearchBoxAfter = sender.SeachBoxText; // new search box text is saved to local variable // if the new text is shorter than the previous text in the Search box, then search in the "old" XML file (before change) // the new text also should be not empty if (SearchBoxAfter.Length < searchBox.Length && SearchBoxAfter.Length >= 0) { ReadXMLPreviousResults(); // read the "old" XML TableFromModel = null; // reset the 2D array TableFromModel = new string[MyTable.Rows.Count][]; // set new size (rows count) for the new data to be sent to the GUI // update the "new" 2D array with the updated data from the internal DataTable with the latest results for (int i = 0; i < MyTable.Rows.Count; i++) { TableFromModel[i] = new string[6]; // initialize each new row in the 2D array for (int j = 0; j < TableFromModel[i].Length; j++) // fill each row in the 2D array with the "updated" data from the DataTable { TableFromModel[i][j] = MyTable.Rows[i].Field <string>(j); // populate each column in the new row } } if (GridWasChanged != null) // check if Form1 class has signed up for the new grid size event { GridWasChanged(this); // if the Grid was changed, then trigger the proper method in Form1 class sender.TableContr = TableFromModel; // send the new data after search via the public 2D array if (TableFromModel == null) // if nothing was found , then just set the new DataGrid size to 0, it will show empty DataGrid in GUI { sender.NewGridSize = 0; // send new 0 size if nothing was found } else { sender.NewGridSize = TableFromModel.Length; // send the new DataGrid size if at least 1 row was found } } } UserView_SearchButtonPushed(sender); // perform automatic search with the new text from Search Box, it is similar to } // pushing the Search button, which is not visible in our GUI
// sign up for Add Button event public void AddButtonPrepare(IViewGUI userView) { userView.AddButtonPushed += UserView_AddButtonPushed; }
public void SearchBoxTextChangedSignUp(IViewGUI userView) // any changes in the Search box { userView.SearchBoxTextChanged += UserView_SearchBoxTextChanged; }
public void OpenFormSignUp(IViewGUI userView) // 1st start of the Form { userView.FormOpened += UserView_FormOpened; }
public void SaveButtonSignUp(IViewGUI userView) { userView.SaveButtonPushed += UserView_SaveButtonPushed; }
public void SearchButtonSignUp(IViewGUI userView) { userView.SearchButtonPushed += UserView_SearchButtonPushed;; }
// methods for preparing for the button push events in the GUI public void AddButtonSignUp(IViewGUI userView) { userView.AddButtonPushed += UserView_AddButtonPushed; }
// the methid is started when the Add button was pushed in GUI private void UserView_AddButtonPushed(IViewGUI sender) { // initialize new DataTable for storing temporary results, and comparing them to the current results, in order to avoid adding duplicates to the DataGrid DataTable CompareTable = new DataTable(); // initialize standard columns for new temporary DataTable CompareTable.Columns.Add("Title", typeof(string)); CompareTable.Columns.Add("Artist", typeof(string)); CompareTable.Columns.Add("Album", typeof(string)); CompareTable.Columns.Add("Genre", typeof(string)); CompareTable.Columns.Add("Year", typeof(string)); CompareTable.Columns.Add("FilePath", typeof(string)); DataRow CurrentRow = CompareTable.NewRow(); // initialize a new row for the temporary DataTable ModifiedGridSize = 0; // size of the grid before adding is 0 TableFromModel = sender.TableContr; // receive Tag data from the Controller class to the internal 2D array (TableFromModel) // if the result DataTable, and the Grid are empty , then there will be no duplicates, and there is no need to compare Table results with the new ones if (MyTable.Rows.Count == 0) { for (int i = 0; i < TableFromModel.GetLength(0); i++) // adding new rows to the DataTable according to the files from the OpenDialog in the GUI { // add new row with the tag data to the current DataTable MyTable.Rows.Add(TableFromModel[i][0], TableFromModel[i][1], TableFromModel[i][2], TableFromModel[i][3], TableFromModel[i][4], TableFromModel[i][5]); ModifiedGridSize++; // the Grid size is increased } // the new size event is triggered in the Form1 class, and the new size with the new data is send to GUI if (GridWasChanged != null) { GridWasChanged(this); sender.TableContr = TableFromModel; // send the new data back to DataGrid if (TableFromModel == null) { sender.NewGridSize = 0; // if there was no new data then send 0 results } else { sender.NewGridSize = TableFromModel.Length; //send the new size of the Grid to the GUI class - Form1 } } } else // if there was data in the DataGrid already then compare each row in the Grid against each new row { for (int i = 0; i < TableFromModel.GetLength(0); i++) { // Add new row from the new file to the temporary table CompareTable.Rows.Add(TableFromModel[i][0], TableFromModel[i][1], TableFromModel[i][2], TableFromModel[i][3], TableFromModel[i][4], TableFromModel[i][5]); // compare this new row against each exisitng rowin the current DataTable by using LINQ intersect command simmilar to the SQL query with intersect var result = CompareTable.AsEnumerable().Intersect(MyTable.AsEnumerable(), DataRowComparer.Default); // if there is no duplicate rows in the exisiting results, then it is allowed to add a new row to the current DataTable if (result.Count <DataRow>() == 0) { ModifiedGridSize++; // increase the Grid size // add the new row to the current DataTable without any duplicates MyTable.Rows.Add(TableFromModel[i][0], TableFromModel[i][1], TableFromModel[i][2], TableFromModel[i][3], TableFromModel[i][4], TableFromModel[i][5]); } CompareTable.Clear(); // clean the temporary Datatable for the new compare cycle } // update the 2D array with the new non-duplicated results for sending it back to the Grid/GUI TableFromModel = null; // clean 2D array before populating TableFromModel = new string[MyTable.Rows.Count][]; // initialize 2D array with the new empty rows/new size for (int i = 0; i < MyTable.Rows.Count; i++) { TableFromModel[i] = new string[6]; // initialize new row in the datatable for (int j = 0; j < TableFromModel[i].Length; j++) // go through each column in the row { TableFromModel[i][j] = MyTable.Rows[i].Field <string>(j); // fill the 2D array with the new data } } if (GridWasChanged != null) { GridWasChanged(this); // fire change Grid event sender.TableContr = TableFromModel; // send the new data to the Grid via 2D array if (TableFromModel == null) { sender.NewGridSize = 0; // send the 0 size if nothing was added } else { sender.NewGridSize = TableFromModel.Length; // send the new Grid size after adding } } } UpdateXMLPreviousResults(); // Save current DataTable to XML after adding a new batch of files, because after adding we have an initial result set for the future searches // and in case if form is closed then at 1st run this data will be retreived from "previous" XML }
} // pushing the Search button, which is not visible in our GUI // The method is called when the Search button is pushed, but because this button is invisible, the method is called automatically, // when the text is changed the Search box private void UserView_SearchButtonPushed(IViewGUI sender) { searchBox = sender.SeachBoxText; // save the search word to local string if (TableFromModel != null) // if local 2D array is not empty, the perform Search on the Grid { foreach (DataRow resultedRow in MyTable.Rows) // Creat new table from old table based on search filter { // compare the text in the search box to each column (Tag) in the DataRow if (resultedRow["Title"].ToString().ToLower().Contains(searchBox.ToLower()) || resultedRow["Artist"].ToString().ToLower().Contains(searchBox.ToLower()) || resultedRow["Album"].ToString().ToLower().Contains(searchBox.ToLower()) || resultedRow["Genre"].ToString().ToLower().Contains(searchBox.ToLower()) || resultedRow["Year"].ToString().ToLower().Contains(searchBox.ToLower()) || resultedRow["FilePath"].ToString().ToLower().Contains(searchBox.ToLower())) { DataRow newRow = UpdatedTable.NewRow(); // if found at least in one column , then initialize the new row in the temporary DataTable newRow.ItemArray = resultedRow.ItemArray.Clone() as object[]; // copy one full row from the current DataTable to the temporary DataTable UpdatedTable.Rows.Add(newRow); // copy from initial DataTable to the temporary DataTable } } // if nothing was found than "new" and "old" DataTables should be the same size if (UpdatedTable.Rows.Count != MyTable.Rows.Count) { ModifiedGridSize = UpdatedTable.Rows.Count; // update the new size of the DataGrid, for sending it to Form1 class // if nothing was found then "new" Updated DataTable has 0 rows, // otherwise copy all data from "new" DataTable to 2D array for sending it to Form1 via event "GridWasChanged" if (UpdatedTable.Rows.Count > 0) { TableFromModel = null; // reset the 2D array before writing new data TableFromModel = new string[UpdatedTable.Rows.Count][]; // initialize 2D array with the new size for (int i = 0; i < UpdatedTable.Rows.Count; i++) // { TableFromModel[i] = new string[6]; // initialize new row with 6 columns like in the DataTable for (int j = 0; j < TableFromModel[i].Length; j++) { TableFromModel[i][j] = UpdatedTable.Rows[i].Field <string>(j); // copy all data from the temporary DataTable with search results to the } // 2D array for sending it to the Form1 / GUI } if (GridWasChanged != null) { GridWasChanged(this); // Grid was certainly changed after search if (TableFromModel != null) { sender.TableContr = TableFromModel; // send new data to the GUI if (TableFromModel == null) { sender.NewGridSize = 0; // if nothing was found send the new 0 size } else { sender.NewGridSize = TableFromModel.Length; // else send the poper "updated" Grid size } } } } else // if search has found nothing, then send empty table to the GUI and new size of the Grid is 0 { TableFromModel = null; // clear DataTable if (GridWasChanged != null) { GridWasChanged(this); sender.TableContr = TableFromModel; // send the empty results to the Grid/GUI if (TableFromModel == null) { sender.NewGridSize = 0; } else { sender.NewGridSize = TableFromModel.Length; } } } } MyTable.Clear(); // clear the internal results table, before writing the new data after search MyTable = UpdatedTable.Copy(); // copy all results of the search from temporary table to the current DataTable UpdatedTable.Clear(); // clan the temporary DataTable } UpdateXMLNewResults(); // update the current XML file with the search results }