DataView.RowFilter not reflected back to DataGridView - dataset

I created an Access Database with 3 tables (Recs, Artist, Album)
I want to filter the DataSet (Recs) on an Album Title but the DataView.RowFilter is not reflected back to the DataGridView.
TaggerDataSet is the container for Recs, Artist, Album tables dgvRecs is my DataGridView for the Recs Table dgvArtist is my DataGridView for the Artist Table dgvAlbum is my DataGridView for the Album Table
to reference the Recs Table I use TaggerDataSet.Recs to reference the Artist Table I use TaggerDataSet.ArtistTable to reference the Album Table I use TaggerDataSet.AlbumTable
Private Sub SetRecFilter(SQLFilter As String, LookFor As String)
'The SQL filter contains "AlbumTitle = Taken By Force"
'LookFor is for testing and contains "Taken By force"
Dim DView As DataView 'To get the Data View from the table 'Recs'
Dim DTable As DataTable 'To get the Recs table from the Dataset
Dim DVal(0) As Object 'For Testing of the Data View
Dim Index As Integer 'Index into the Table Records
DTable = TaggerDataSet.Recs 'This gets the Recs table from the Dataset
DView = New DataView(DTable) 'This associates the Data View to the DataTable
DView.Sort = "AlbumTitle" 'Needed for the Find request
DVal(0) = LookFor 'Sets the object to the passed in LookFor value
Index = DView.Find(DVal) 'Index returns a value of 4 (which is correct)
'This call is confirmed to work (the DView.count is changed from 7 to 1)
'but has no effect on TaggerDataSet.Recs (TaggerDataSet.Recs.Rows.Count still at 7)
DView.RowFilter = SQLFilter 'This changes the record count to 1 (which is correct)
DTable = DView.ToTable 'This saves the Table back to the Data Table
'This call also has no effect
TaggerDataSet.Tables(2).DefaultView.RowFilter = SQLFilter 'This has no effect
'This call also has no effect even though the table is specifically referenced
TaggerDataSet.Recs.DefaultView.RowFilter = SQLFilter
Validate()
TaggerDataSetBindingSource.EndEdit()
TaggerDataSetBindingSource.Filter = SQLFilter
RecsTableAdapter.Fill(TaggerDataSet.Recs)
RecsTableAdapter.Update(TaggerDataSet.Recs)
TableAdapterManager.UpdateAll(TaggerDataSet)
dgvRecs.Refresh()
dgvRecs.FirstDisplayedScrollingRowIndex = 0
End Sub
Solved this problem (at least for a short test) with:
dgvRecs.DataMember = ""
dgvRecs.DataSource = DTable.DefaultView
just after the DTable = DView.ToTable line
Everything after that may not be needed any more.
I now have a new problem. Resetting the RowFilter to "" or to Nothing leaves the first column after the ID blank (All Song Titles are blank)
I have tried the following:
DTable = TaggerDataSet.ArtistTable
DView = New DataView(DTable)
DView.RowFilter = Nothing
DTable = DView.ToTable
dgvArtist.DataSource = ""
dgvArtist.Refresh()
dgvArtist.DataSource = ArtistDataGridViewSource
dgvArtist.DataMember = ArtistDataGridViewMember
Validate()
TaggerDataSetBindingSource.EndEdit()
ArtistTableTableAdapter.Update(TaggerDataSet.ArtistTable)
Me.ArtistTableTableAdapter.Fill(Me.TaggerDataSet.ArtistTable)
TableAdapterManager.UpdateAll(TaggerDataSet)
dgvArtist.Refresh()
where ArtistDataGridViewSource was set when the form was loaded with the original DataSource and the same with the DataMember.

Related

Listbox does not add item to its list. If I use selection.None

I am using an array to populate my listbox. It worked fine but when I set the listbox.selection.none (I don't want items to be selected) then My listbox adds item to its first index but after that. It keeps the same value in an does not add new values. below is the code what i am using to add items to listbox from array.
Private array(10) As Decimal ' adds student score to array
dim index as integer = 0 '
Private Sub PopulateScoreList() ' method called when button is clicked
If index < 10 Then
' adds value to array at every button click event
array(index) = Math.Round(value, 1)
End If
index += 1
lbxTroopersScore.DataSource = Nothing
lbxTroopersScore.DataSource = array
end sub
Seems like a bug. Toggling the SelectionMode property fixes the problem:
lbxTroopersScore.DataSource = Nothing
lbxTroopersScore.SelectionMode = SelectionMode.One
lbxTroopersScore.SelectionMode = SelectionMode.None
lbxTroopersScore.DataSource = array

Unsure which join to use with with the following sql code

i have 2 tables. I am wanting to insert some values into 1 table. The fields i am updating is ingredient_Name, Ingredient_Amount and Recipe_ID.
Ingredient (Table 1)
Ingredient_Name|Ingredient_Amount|Recipe_ID
---------------|-----------------|--------- <---- Insert into here
Recipe (Table 2)
Recipe_Name|Recipe_ID
yummyRecipe|----1---- <-----Recipe_ID stored here
The form i am using has a comboBox which lists all Recipe_Names. So when i go to insert a row into ingredients i need to fetch the Recipe_ID from the Recipe table where i have selected the Recipe_Name in the comboBox. Then use this Recipe_ID for the ID in the Ingredients table.
I am not very familiar with JOINs and unsure how to work out what one to use and if i need to use one. Any help or ideas?
Sorry if this is too long winded.
Recipe ComboBox Code
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0; AttachDbFilename=C:\Users\Donald\Documents\Visual Studio 2013\Projects\DesktopApplication\DesktopApplication\Student_CB.mdf ;Integrated Security=True");
con.Open();
try
{
SqlDataAdapter da = new SqlDataAdapter("Select * FROM Recipe", con);
DataTable dt = new DataTable();
da.Fill(dt);
for (int i = 0; i < dt.Rows.Count; i++)
{
recipeCombo.Items.Add(dt.Rows[i]["Recipe_Name"]);
}
dt.Clear();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
con.Close();
You can set the ComboBox items using directly the DataSource and control which field you want to display using the DisplayMember property. Together with the ValueMember property you could write
using(SqlConnection con = new SqlConnection(....))
{
con.Open();
try
{
SqlDataAdapter da = new SqlDataAdapter("Select * FROM Recipe", con);
DataTable dt = new DataTable();
da.Fill(dt);
recipeCombo.DataSource = dt;
recipeCombo.DisplayMember = "Recipe_Name";
recipeCombo.ValueMember = "Recipe_ID";
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
Now in the ComboBox_SelectedIndexChanged event (or everywhere you need to know the RecipeID you just have to write
if(recipeCombo.SelectedItem != null)
{
int recipeID = Convert.ToInt32(recipeCombo.SelectedValue);
... and use your value for insert without any JOIN
}
In whichever point you need, (for example in a SAVE button click event) add the following INSERT
if(recipeCombo.SelectedItem == null)
.... error message and return....
else
string sql = #"INSERT INTO Ingredient
(Ingredient_Name, Ingredient_Amount, Recipe_ID)
VALUES (#IngredientName, #IngredientFirstname, #RecipeID)";
using (var cmd = new SqlCommand(sql, con))
{
cmd.Parameters.Add("#IngredientName", SqlDbType.NVarChar).Value = ingredientTxt.Text);
cmd.Parameters.Add("#IngredientAmount", SqlDbType.Integer).Value = Convert.ToInt32(ingredientAmount.Text);
cmd.Parameters.Add("#RecipeID", SqlDbType.Integer).Value = Convert.ToInt32(recipeCombo.SelectedValue);
cmd.ExecuteNonQuery();
}
PS. Do not use AddWithValue - it is a shortcut with a lot of problems -
You do not need a JOIN in your case because you have only one table "Recipe" that contains the data you need to find "Recipe_ID". JOINs are used to "join" two tables.
If "Recipe_Name" is identical you can select the "Recipe_ID" where the "Recipe_Name" is equal to the selected value from the combobox then insert the new row to the "Ingredient" table.
INSERT INTO Ingredient SELECT #Ingredient_Name, #Ingredient_Amount, Recipe_ID FROM Recipe WHERE Recipe_ID = #myComboboxSelectedValue
Note: In this case Recipe_ID is redundant because you can remove it from your database and use Recipe_Name instead.
If "Recipe_Name" is not identical so you will need to fetch "Recipe_ID" with it and store it in the code-behind (if you do not want to show it to the user) and use it in your insert query.
By the way:
4. Whether using MYSQL or SQLSERVER the solution is the same, so "using .mdf" in the title of the question is irrelevant.
5. ".mdf" files are the extensions for SQLSERVER databases.

VB.NET dataset displaying database rows incorrectly

I would say I'm new to VB but I have been using it for over a year although for mainly small tasks (mostly school related). Anyway my current project is for my A-Level task and I need to be able to add, update, delete and read from a database. My current code allows this to happen but after a new record is added to my database the dataset in VB displays the rows differently. I have 3 tables: "PlayerInfo", "PlayerSkill" and "PlayerAbilities". when a new record is added; the new "PlayerInfo" information becomes the first row in my dataset while the "PlayerSkill" and "PlayerAbilities" become the last row. This causes all of the information to be improperly matched up. I was wondering if anyone else has had this problem and if they know how to solve it.
This shows the working code to add to my database.
If inc <> -1 Then
Dim cb1 As New OleDb.OleDbCommandBuilder(da1)
Dim cb2 As New OleDb.OleDbCommandBuilder(da2)
Dim cb3 As New OleDb.OleDbCommandBuilder(da3)
Dim dsNewRow1 As DataRow
Dim dsNewRow2 As DataRow
Dim dsNewRow3 As DataRow
Try
dsNewRow1 = ds1.Tables("Players").NewRow()
dsNewRow1.Item("Forename") = Forename.Text()
dsNewRow1.Item("Surname") = Surname.Text()
ds1.Tables("Players").Rows.Add(dsNewRow1)
da1.Update(ds1, "Players")
dsNewRow3 = ds3.Tables("Players").NewRow()
dsNewRow3.Item("Reactions") = Reactions.Text()
dsNewRow3.Item("Strength") = Strength.Text()
dsNewRow3.Item("Speed") = Speed.Text()
dsNewRow3.Item("Stamina") = Stamina.Text()
dsNewRow3.Item("Accuracy") = Accuracy.Text()
dsNewRow3.Item("Coordination") = Coordination.Text()
ds3.Tables("Players").Rows.Add(dsNewRow3)
da3.Update(ds3, "Players")
dsNewRow2 = ds2.Tables("Players").NewRow()
dsNewRow2.Item("RegularShot") = RegularShot.Text()
dsNewRow2.Item("ShortServe") = ShortServe.Text()
dsNewRow2.Item("FlickServe") = FlickServe.Text()
dsNewRow2.Item("Clear") = Clear.Text()
dsNewRow2.Item("Smash") = Smash.Text()
dsNewRow2.Item("DropShot") = DropShot.Text()
ds2.Tables("Players").Rows.Add(dsNewRow2)
da2.Update(ds2, "Players")
MsgBox("New Record added to the Database")
Commit.Enabled = False
AddNew.Enabled = True
Update.Enabled = True
Delete.Enabled = True
Catch
MsgBox("Error")
Me.Close()
End Try
End If
This shows the code that displays each of the dataset records inside different text boxes.
Try
Forename.Text = ds1.Tables("Players").Rows(inc).Item(1)
Surname.Text = ds1.Tables("Players").Rows(inc).Item(2)
Speed.Text = ds3.Tables("Players").Rows(inc).Item(3)
Strength.Text = ds3.Tables("Players").Rows(inc).Item(2)
Reactions.Text = ds3.Tables("Players").Rows(inc).Item(1)
Stamina.Text = ds3.Tables("Players").Rows(inc).Item(4)
Coordination.Text = ds3.Tables("Players").Rows(inc).Item(6)
Accuracy.Text = ds3.Tables("Players").Rows(inc).Item(5)
ShortServe.Text = ds2.Tables("Players").Rows(inc).Item(2)
FlickServe.Text = ds2.Tables("Players").Rows(inc).Item(3)
Clear.Text = ds2.Tables("Players").Rows(inc).Item(4)
Smash.Text = ds2.Tables("Players").Rows(inc).Item(5)
DropShot.Text = ds2.Tables("Players").Rows(inc).Item(6)
RegularShot.Text = ds2.Tables("Players").Rows(inc).Item(1)
Catch
MsgBox("Error")
Me.Close()
End Try
Sadly I do not currently have enough "Rep" to upload a picture of the dataset.
Also sorry if this is not enough information, I'm not really used to using forums and such.
I'm not entirely sure if this counts as an answer as I still don't know what caused the problem in the first case. Anyway I've got my code doing what I wanted by editing the SQL statements to display the rows in order of the primary key. ORDER BY [Player#]. I did have to change the name to just "Player" because the "CommandBuilder" doesn't like special characters.

Create DataGrid in WPF at runtime

There is a DataGridView which is created at runtime with data fetching from database. There are four types of columns in data grid view:
DataGridViewTextBoxColumn
DataGridViewComboboxColumn
DataGridViewButtonColumn
DataGridViewCheckBoxColumn
Code for creating that datagridview is as below:
_form.DGV_.AutoGenerateColumns = False
_form.DGV_.Columns.Clear()
'Required Variables
Dim pom_DataGridViewTextBoxColumn As DataGridViewTextBoxColumn = Nothing
Dim pom_DataGridViewComboBoxColumn As DataGridViewComboBoxColumn = Nothing
Dim pom_DataGridViewButtonColumn As DataGridViewButtonColumn = Nothing
Dim pom_DataGridViewCheckBoxColumn As DataGridViewCheckBoxColumn = Nothing
'Column-1 (ID: jntDate)
pom_DataGridViewTextBoxColumn = New DataGridViewTextBoxColumn
pom_DataGridViewTextBoxColumn.DataPropertyName = "jntDate"
pom_DataGridViewTextBoxColumn.HeaderText = "Date"
pom_DataGridViewTextBoxColumn.DefaultCellStyle.Format = "d"
_form.DGV_.Columns.Add(pom_DataGridViewTextBoxColumn)
'Column-2 (ID: jntAcc)
pom_DataGridViewComboBoxColumn = New DataGridViewComboBoxColumn
pom_DataGridViewComboBoxColumn.DataPropertyName = "jntAcc"
'Cond: If dataset Acc does not contain any table then add table from database.
If Acc.Tables.Count > 0 Then
pom_DataGridViewComboBoxColumn.DataSource = Acc.Tables.Item(0)
Else
Acc.Tables.Add(Tbl_Select("SELECT *, accNo AS byNo, accName as byName FROM tblAccounts", False, ""))
pom_DataGridViewComboBoxColumn.DataSource = Acc.Tables.Item(0)
End If
'Cond: If _Account_Name_Number is True then set DisplayMember property to 'byName'.
If _Account_Name_Number Then
pom_DataGridViewComboBoxColumn.DisplayMember = "byName"
Else
pom_DataGridViewComboBoxColumn.DisplayMember = "byNo"
End If
pom_DataGridViewComboBoxColumn.ValueMember = "accID"
pom_DataGridViewComboBoxColumn.HeaderText = "Account"
_form.DGV_.Columns.Add(pom_DataGridViewComboBoxColumn)
'Column-3 (ID: xxxx)
pom_DataGridViewButtonColumn = New DataGridViewButtonColumn
pom_DataGridViewButtonColumn.DataPropertyName = "xxxx"
pom_DataGridViewButtonColumn.UseColumnTextForButtonValue = True
pom_DataGridViewButtonColumn.HeaderText = "X"
pom_DataGridViewButtonColumn.Text = "X"
pom_DataGridViewButtonColumn.Width = 32
pom_DataGridViewButtonColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
pom_DataGridViewButtonColumn.DefaultCellStyle.ApplyStyle(pom_DataGridViewButtonColumn.DefaultCellStyle)
_form.DGV_.Columns.Add(pom_DataGridViewButtonColumn)
'Column-4 (ID: jntReview)
pom_DataGridViewCheckBoxColumn = New DataGridViewCheckBoxColumn
pom_DataGridViewCheckBoxColumn.DataPropertyName = "jntReview"
pom_DataGridViewCheckBoxColumn.HeaderText = "Review"
pom_DataGridViewCheckBoxColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
pom_DataGridViewCheckBoxColumn.DefaultCellStyle.ApplyStyle(pom_DataGridViewCheckBoxColumn.DefaultCellStyle)
_form.DGV_.Columns.Add(pom_DataGridViewCheckBoxColumn)
In WPF application, there is a need to populate same DataGrid with these four columns.
How can I create and bind data to four types of columns in DataGrid in WPF ?
Why not skip doing all that stuff in cs code? You'll start pinning yourself in the corner and WILL hit the wall when the datagrid will need more complex templates, data triggers, custom styles, animations, etc... Besides, it will make it easier not only on the next person, but you as well. When you have to add/fix something in the beast you create in .cs code 3-6 months down the road, it might take you quite a while to understand what is going on :)
Instead, do all your work in xaml, Create a UserControl, put this datagrid in it, Pass the DataContext from various instances of the UserControl down to it's DataGrid.

DataGridViewComboBoxCell Value Not Updating When Set Programmatically C# Winforms

I've read all the similiar posts about this darn control (DataGridViewComboBoxCell) and setting it's value programmatically but implementing all the suggestions hasn't worked. I could probably change the UI to get around this problem but I don't like to be beat!
private void PopulateAreaForRoleAssociation()
{
// If businessRoleList is null then no data has been bound to the dgv so return
if (businessRoleList == null)
return;
// Ensure businessArea repository is instantiated
if (businessAreaRepository == null)
businessAreaRepository = new BusinessAreaRespository();
// Get a reference to the combobox column of the dgv
DataGridViewComboBoxColumn comboBoxBusinessAreaColumn = (DataGridViewComboBoxColumn)dgvBusinessRole.Columns["BusinessArea"];
// Set Datasource properties to fill combobox
comboBoxBusinessAreaColumn.DisplayMember = "Name";
comboBoxBusinessAreaColumn.ValueMember = "Id";
comboBoxBusinessAreaColumn.ValueType = typeof(Guid);
// Fill combobox with businessarea objects from list out of repository
comboBoxBusinessAreaColumn.DataSource = businessAreaRepository.GetAll();
// loop through the businessRoles list which the dgv is bound to and get out each dgv row based upon the current id in the loop
businessRoleList.Cast<BusinessRole>().ToList().ForEach(delegate(BusinessRole currentRole)
{
DataGridViewRow currentRowForRole = dgvBusinessRole.Rows.Cast<DataGridViewRow>().ToList().Find(row => ((BusinessRole)row.DataBoundItem).Id == currentRole.Id);
// Get a reference to the comboBox cell in the current row
DataGridViewComboBoxCell comboBoxCell = (DataGridViewComboBoxCell)currentRowForRole.Cells[2];
// Not sure if this is necessary since these properties should be inherited from the combobox column properties
comboBoxCell.DisplayMember = "Name";
comboBoxCell.ValueMember = "Id";
comboBoxCell.ValueType = typeof(Guid);
// Get the business area for the current business role
BusinessArea currentAreaForRole = businessAreaRepository.FetchByRoleId(currentRole.Id);
// if the role has an associated area then set the value of the cell to be the appropriate item in the combobox
// and update the cell value
if (currentAreaForRole != null)
{
foreach (BusinessArea area in comboBoxCell.Items)
{
if (currentAreaForRole.Id == area.Id)
{
comboBoxCell.Value = area.Id;
dgvBusinessRole.UpdateCellValue(2, comboBoxCell.RowIndex);
}
}
}
});
}
The dgv is first bound to a binding list holding BusinessRole objects, then the combobox column is bound to a basic list of BusinessArea objects that come out of a repository class. I then loop through the bindinglist and pull out the row of the dgv that is bound to the current item in the bindinglist loop.
With that row I make a database call to see if the BusinessRole entity is associated with a BusinessArea entity. If it is then I want to select the item in the combobox column that holds the BusinessAreas.
The problem is that when the grid is loaded, all the data is there and the comboboxes are populated with a list of available areas, however any values that are set are not displayed. The code that sets the value is definately getting hit and the value I am setting definately exists in the list.
There are no data errors, nothing. It's just refusing to update the UI with the value I programmatically set.
Any help would be greatly appreciated as always.
Thanks
This code works for my first combo box I have in my row with the following code, but I try it with the next one in the row and it doesn't work. I could use the help with the rest I have 3 more to do. I do set the combo boxes on a second form from this form with the same code as is on the last line of the try block but using the cell information instead of the dataset
try
{
string strQuery = "select fundCode from vwDefaultItems where IncomeType = '" + stIncome + "'";
SqlDataAdapter daDefault = new SqlDataAdapter(strQuery, conn);
DataSet dsDefault = new DataSet();
daDefault.Fill(dsDefault);
strDefFund = dsDefault.Tables[0].Rows[0].ItemArray[0].ToString();
dgvCheckEntry.Rows[curRow].Cells[7].Value = dsDefault.Tables[0].Rows[0].ItemArray[0].ToString();
}
catch (Exception eq)
{
}

Resources