I have a very basic question I want to update DataGridView using this code
private void updateDGV1_Click(object sender, EventArgs e)
{
SQLiteConnection sqliteCon = new SQLiteConnection(dbConnectionString);
// open connection to database
try
{
cmbl1 = new SQLiteCommandBuilder(datadp1);
datadp1.Update(ds1, "PlotDetails");
MessageBox.Show("Information Updated", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
load_table();
AutoCompleteSizeSearch();
AutoCompletePlotSearch();
AutoCompleteOwnerSearch();
AutoCompleteLocatoinSearch();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
After search for a result using this code
private void plots_txt_TextChanged(object sender, EventArgs e)
{
DataView dv = new DataView(dt1);
dv.RowFilter = string.Format("D_ID LIKE '%{0}' AND Area LIKE '%{1}' AND Cat LIKE '%{2}' AND PBS LIKE '%{3}%' AND Name LIKE '%{4}%' AND Size LIKE '%{5}%' AND Location LIKE '%{6}%' AND PlotNo LIKE '%{7}%'", dids_combo.Text, areacs_txt.Text, categorycs_txt.Text, phblses_txt.Text, owners_txt.Text, sizes_txt.Text, locations_txt.Text, plots_txt.Text);
dataGridView1.DataSource = dv;
}
After getting result of search I couldn't been able to update searched result.
updateDGV1_Click works fine on the whole DGV but not on Searched result like in below image
After search,result not updating
I would actually recommend using the TableAdapter to communicate with your database instead of generating a connection in that fashion. This will also allow you to easily update your DataGridView with the contents of the TableAdpater Query (Search) that you want to preform. I wish I could go into more detail but I'm in a hurry at the moment I will provide links explaining this better below.
https://msdn.microsoft.com/en-us/library/bz9tthwx.aspx
I personally use TableAdapters to connect databases in my projects, but I have found a solution that may also allow you to keep your code the way it is for the most part.
http://www.codeproject.com/Articles/14249/How-to-populate-DataGridView-GridView-with-SQL-sta
What you will need to do when you want to preform a search on the current working DataSet. This code is an example I haven't tested it.
string conn_str = "Data Source=dbServer;Initial Catalog=testDB;Integrated Security=True";
string sql_str = “select * from table1”;
SqlDataAdapter data_adapter = new SqlDataAdapter(sql_str, conn_str);
SqlCommandBuilder cmd_builder = new SqlCommandBuilder(data_adapter);
// Populate a new data table and bind it to the BindingSource.
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
// This line populates our new table with the data from our sql query
data_adapter.Fill(table);
db_binding_source.DataSource = table;
// Resize the DataGridView columns to fit the newly loaded content.
data_grid_view.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
// you can make it grid readonly.
data_grid_view.ReadOnly = true;
// finally bind the data to the grid
data_grid_view.DataSource = db_binding_source;
Here is also another answer on SO similar to what you're asking
How do I Update/Reload DataGridView BindingSource?
Related
I can save data in my gridView but I am unable to do so to my datasource.
Could there a missing line of code or is there something that I am missing?
Here's my code:
public Marksheet(object val1)
{
InitializeComponent();
string connectionString = null;
SqlConnection conn;
connectionString = "Server=localhost\\SQLEXPRESS;Integrated security=SSPI;database=jms";
SqlDataAdapter sda6 = new SqlDataAdapter("SELECT * FROM grades WHERE class_code='" + val1 + "'", connectionString);
conn = new SqlConnection(connectionString);
DataTable dt5 = new System.Data.DataTable();
sda6.Fill(dt5);
gridControl1.DataSource = dt5;
}
private void gridControl1_EmbeddedNavigator_ButtonClick(object sender, NavigatorButtonClickEventArgs e)
{
if (e.Button.ButtonType == DevExpress.XtraEditors.NavigatorButtonType.EndEdit)
{
if (MessageBox.Show("Do you want to commit changes to the current record?", "Confirm commit",
MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) != DialogResult.No)
{
gridView1.CloseEditor();
gridView1.UpdateCurrentRow();
}
}
}
private void gridView1_CellValueChanged(object sender, CellValueChangedEventArgs e)
{
//?? Could there be something I'm missing here? if yes, what could it be?
}
When you make any changes to the grid control, the changes are reflected in the datasource, that is in your case a DataTable. If you think logically, it seems correct as the Grid Control is bound to the DataTable and is not aware about how the DataTable gets populated.
Now you can see that the DataTable is populated using DataAdapter. You need to call the DataAdapter.Update(dataTable) method to push the changes to database.
As described here - Posting Data to a Connected Database
The best approach is already suggested by #Aseem that you need to implement ADO.net binding to commit changes back to the back-end using the DataAdapter. If you can implement this way then check below tutorial:
Tutorial: ADO.NET Data
When binding to a database using ADO.NET, you bind a control to a
DataTable containing data from the database. When you change data via
the Grid Control (adding, deleting or modifying records), the changes
are accumulated in the DataTable. They are not automatically posted to
the underlying database. Therefore, you need to manually call a
specific method to post the changes.
If you are using custom data table and not willing to implement such binging then you have to handle GridView.RowUpdated Event and then you can post back then changes that you made in current updated row.
Refer this: Xtragrid Row Updated Event
Example:
Private Sub gridView1_RowUpdated(ByVal sender As System.Object, ByVal e As DevExpress.XtraGrid.Views.Base.RowObjectEventArgs) Handles gridView1.RowUpdated
Dim val As Object
Dim row As DataRowView = CType(e.Row, DataRowView)
val = row(0)
End Sub
Hope this help..
I have 2 datagridview's that i am trying to sort by one specific column. What I am trying to do is when the program starts I want the DGV to automatically sort by one column by descending. I have been searching and I cannot seem to find what I am looking for.
Here are images of what I am asking. I want the journalID column to start at highest first and descend from there.
Thanks in advance
private void Form1_Load(object sender, EventArgs e)
{
string connectionstring = #"Data Source=|DataDirectory|\Database1.sdf";
SqlCeConnection connection = new SqlCeConnection(connectionstring);
SqlCeCommand command = new SqlCeCommand(" SELECT * FROM journalTbl ORDER BY journalId DESC ;", connection);
try
{
SqlCeDataAdapter adapter = new SqlCeDataAdapter();
adapter.SelectCommand = command;
DataTable datatable = new DataTable();
adapter.Fill(datatable);
BindingSource bindingsource = new BindingSource();
bindingsource.DataSource = datatable;
dataGridView1.DataSource = bindingsource;
adapter.Update(datatable);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Create a connection to the database and select the desired table via
a command
Include specific functions in the command (in this case ordering by journalId Desending)
Create a data adapter to allow communication between the dataset and the datasource
Create a datatable and fill via the data adapter
Create a binding source and assign it to the datatable
Set the datagridview datasource as the binding source.
Update the adapter
Order By SQL - SQL Reference
Order By clause C# MSDN Reference
Please Note: Order by will automatically order by Ascending. I am also using Sql Compact Edition.
I will just add these lines on your Form1_Load(...) method.
DataGridViewColumn columnToSort = dataGridView1.Columns["ColumnNameToSortGoesHere"];
dataGridView1.Sort(columnToSort, ListSortDirection.Descending);
You don't should use Code Behind. You should study MVVM model and Linq library . You work will be better and will be cleaner.
In Model MVVM you solution for this problem is
In your ViewModel
private ObservableCollection<string> _listModelBinding;
public ObservableCollection<string> ListModelBinding
{
get { return _listModelBinding; }
set { _listModelBinding= value; RaisePropertyChanged("ListModelBinding"); }
}
public MainViewModel()
{
ListModelBinding = ListModelBinding.OrderBy(x => x.ToString());
}
In your xaml simply create binding
<DataGrid ItemsSource="{Binding ListModelBinding}" />
That's it.
You can use MVVM in your project using MVVM Light NuGet.
I'm stuck with something and I'd appreciate it if anyone can assist me.
I have a simple MS Access database that's linked to my program. The first thing I did was fill a combobox with one of the fields in my database ("Product Description").
What I'd like to do is when a user selects an item in the combobox, all the other fields in the record be displayed in text boxes.
string sConnection;
sConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=XYZDatabase.accdb";
OleDbConnection dbConn;
dbConn = new OleDbConnection(sConnection);
dbConn.Open();
cbxProducts.DisplayMember = "Product Description";
dbConn.Close();
I've considered using possibly SQL or a DataReader, though I'm really not sure.
This is the event where I want the textboxes to be filled. I'm literally stuck here.
private void cbxProducts_SelectedIndexChanged(object sender, EventArgs e)
{
txtProductNumber.Text =
txtProductDescription.Text =
txtProductCategory.Text =
txtProductCost.Text =
}
I hope I haven't formatted my question wrong or anything, apologies if I have, this is my first time posting here! Dx
I wonder if your combo box is actually showing data from the DB.
In the first code block after
dbConn.Open()
and before
dbConn.Close()
you should have code like this:
SqlCommand sc = new SqlCommand("select prodid, proddesc from products", conn);
SqlDataReader reader;
reader = sc.ExecuteReader();
DataTable dt = new DataTable();
dt.Columns.Add("prodid", typeof(string));
dt.Columns.Add("proddesc", typeof(string));
dt.Load(reader);
cbxProducts.ValueMember = "prodid";
cbxProducts.DisplayMember = "proddesc";
cbxProducts.DataSource = dt;
And then in the second code block you need to fetch the selected Product ID first.
private void cbxProducts_SelectedIndexChanged(object sender, EventArgs e)
{
string ID = comboBox1.SelectedValue.ToString();
//Based on ID make a sql query and fetch the details of that product from the DB.
//Follow the earlier code block to make DB connection and execute query.
//Then populate the data in individual text boxes by looping through the dr.
//I am leaving this deliberately for you to figure out and I am sure you can.
txtProductNumber.Text =
txtProductDescription.Text =
txtProductCategory.Text =
txtProductCost.Text =
}
I created a DataBase named charityah containing 5 tables. Their names are listed in a combobox.
When I choose one of them I want to display their content in a DataGridView.
What I tried is: first I linked the DataGridView to this database and tried this code that I found:
SqlConnection connection = new SqlConnection();
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string s = comboBox1.Text;
connection.ConnectionString = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\Downloads\charityah.mdf;Integrated Security=True";
using (connection)
{
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter("select * from "+s, connection);
DataSet ds = new DataSet();
adapter.Fill(ds, s);
dataGridView1.DataSource = ds.Tables[0];
dataGridView1.Refresh();
}
}
This method doesn't give me any errors and it finds the tables, but nothing is seen in the DataGridView.
Since you report (comments) that there are rows, it sounds like the primary problem (connection disposal aside) is an issue with data-binding. A few thoughts leap to mind:
is the table in virtual mode?
is it adding columns?
do the columns already exist?
You might want to try adding:
dataGridView1.VirtualMode = false;
dataGridView1.Columns.Clear();
dataGridView1.AutoGenerateColumns = true;
before the:
dataGridView1.DataSource = ds.Tables[0];
You might also want to check that dataGridView1.DataMember doesn't have a value assigned.
try this, some times nonsense items do create a lot of mess. so try setting autogenerate columns to true. may this starts showing you the results. because as per your comments, it dosent seems there could be any other issue. so just give it a try
dataGridView1.AutoGenerateColumns = true;
I want to show a master / detail relationship using two datagridviews and DataRelation in C#.
The relation between the master and the detail table is an ID from type string (and there is no chance to change the ID to type integer).
It seems like the DataGridView is not able to update the detail view when changing the row in the master table.
Does anybody know if it is possible to achieve a master / detail view using a string ID and if yes, how? Or do I have to use an external DataGrid from another company?
Personally I don't see a difference in using a string instead of an integer. The only thing I can think of is that the grid cannot handle a master detail view using a string ID relation.
UPDATE: The issue is solved, the problem was that one relation was from type nchar and had blancs at the end of the string. Thanks for the help!
Here is an example, please create a new VS 2008 project and copy the code. Change the connection string and the datarelation:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
public class Form1 : System.Windows.Forms.Form
{
private DataGridView masterDataGridView = new DataGridView();
private BindingSource masterBindingSource = new BindingSource();
private DataGridView detailsDataGridView = new DataGridView();
private BindingSource detailsBindingSource = new BindingSource();
[STAThreadAttribute()]
public static void Main()
{
Application.Run(new Form1());
}
// Initializes the form.
public Form1()
{
masterDataGridView.Dock = DockStyle.Fill;
detailsDataGridView.Dock = DockStyle.Fill;
SplitContainer splitContainer1 = new SplitContainer();
splitContainer1.Dock = DockStyle.Fill;
splitContainer1.Orientation = Orientation.Horizontal;
splitContainer1.Panel1.Controls.Add(masterDataGridView);
splitContainer1.Panel2.Controls.Add(detailsDataGridView);
this.Controls.Add(splitContainer1);
this.Load += new System.EventHandler(Form1_Load);
this.Text = "DataGridView master/detail demo";
}
private void Form1_Load(object sender, System.EventArgs e)
{
// Bind the DataGridView controls to the BindingSource
// components and load the data from the database.
masterDataGridView.DataSource = masterBindingSource;
detailsDataGridView.DataSource = detailsBindingSource;
GetData();
// Resize the master DataGridView columns to fit the newly loaded data.
masterDataGridView.AutoResizeColumns();
// Configure the details DataGridView so that its columns automatically
// adjust their widths when the data changes.
detailsDataGridView.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells;
}
private void GetData()
{
try
{
// Specify a connection string. Replace the given value with a
// valid connection string for a Northwind SQL Server sample
// database accessible to your system.
String connectionString =
"";
SqlConnection connection = new SqlConnection(connectionString);
// Create a DataSet.
DataSet data = new DataSet();
data.Locale = System.Globalization.CultureInfo.InvariantCulture;
// Add data from the Customers table to the DataSet.
SqlDataAdapter masterDataAdapter = new
SqlDataAdapter("select * from customers", connection);
masterDataAdapter.Fill(data, "Customers");
// Add data from the Orders table to the DataSet.
SqlDataAdapter detailsDataAdapter = new
SqlDataAdapter("select * from orders", connection);
detailsDataAdapter.Fill(data, "Orders");
// Establish a relationship between the two tables.
DataRelation relation = new DataRelation("CustomersOrders",
data.Tables["Customers"].Columns["strID"],
data.Tables["Orders"].Columns["strID"]);
data.Relations.Add(relation);
// Bind the master data connector to the Customers table.
masterBindingSource.DataSource = data;
masterBindingSource.DataMember = "Customers";
// Bind the details data connector to the master data connector,
// using the DataRelation name to filter the information in the
// details table based on the current row in the master table.
detailsBindingSource.DataSource = masterBindingSource;
detailsBindingSource.DataMember = "CustomersOrders";
}
catch (SqlException)
{
MessageBox.Show("To run this example, replace the value of the " +
"connectionString variable with a connection string that is " +
"valid for your system.");
}
}
}
I looked through your code and it looks basically OK. Please try to trim it a little further though.
But I find the Field Names "strId" a bit suspicious, is that really what the columns are called in the Database?
Tip: Put a break on the Relations.Add(relation) line and inspect the relation object carefully.
The code doesn't show where/how the bindinsource components are made, maybe they have some designtime properties set (Filter).