save new rows in dataset back out to xml - c#

Can't quite figure out what else I need to do to make this work.
I am trying to add more rows to my dataset and datagridview then output either one to an xml
Ideally I want to save the values in dataset then bind datagridview and when closing the form output the dataset out to an xml file. But for some reason this doesn't work. It does update changes to current rows but doesn't add new rows.
public void LoadSongInfo(string filename)
{
TagLib.File tagFile = TagLib.File.Create(filename);
string artist = tagFile.Tag.FirstAlbumArtist;
string album = tagFile.Tag.Album;
string title = tagFile.Tag.Title;
DataRow newtrack = dsStore.Tables["Track"].NewRow();
newtrack["Id"] = "5";
newtrack["Artist"] = artist;
newtrack["Album"] = album;
newtrack["Filepath"] = filename;
newtrack["Title"] = title;
dsStore.Tables["Track"].Rows.Add(newtrack);
dsStore.Tables["Track"].AcceptChanges();
dataGridView1.DataMember = "Track";
dataGridView1.DataSource = dsStore;
}
private void mediaplayer_FormClosing(object sender, FormClosingEventArgs e)
{
string path = "..//..//..//temp.xml";
dataGridView1.EndEdit();
if (dsStore.GetChanges() != null)
{
dsStore.WriteXml(path);
}
}
I have noticed that
dsStore.GetChanges()
returns null unless cell has been edited. So I tried removing that if statement but still nothing.
EDIT: I've tried to write to an empty xml file to see if it writes at least something, and no errors it goes through like everything is ok, then when i open up test2.xml its blank nothing was written. :(
private void mediaplayer_FormClosing(object sender, FormClosingEventArgs e)
{
string path2 = "..//..//..//test2.xml";
dsStore.WriteXml(path2);
}

You have the line:
dsStore.Tables["Track"].AcceptChanges();
This will update the RowState to 'DataRowState.Unchanged' for every row in that table. This is why
dsStore.GetChanges()
is not returning any changes.
Try removing the AcceptChanges() call.

Try removing the
dataGridView1.EndEdit();
this is used if a cell is being edited so the fact that it's only working when you edit a cell could be caused because of that line.

Ok I got this to work..
First mistake what that I was trying to WriteXml in the LoadSong function which can't be done because that function is being called from a ForEach Loop.
I then went to my FormClosing and just did it this way:
private void mediaplayer_FormClosing(object sender, FormClosingEventArgs e)
{
dsStore.WriteXml(path);
}
And last not sure if it's needed but I set my dataset on top like this:
public DataSet dsStore = new DataSet();
added the "public" in case it wasn't keeping the values..Thanks everyone for you help.

Related

How to format DataGridView to password characters?

Goal:
My goal is to format 1 column to password characters *.
Resources I have tried:
I have used an example from here :
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.datagridview.cellformatting?view=netframework-4.8
and tried this answer here:
https://stackoverflow.com/a/38074239/12485722
This is my current code to load DataGrid View:
private void Form3_Load(object sender, EventArgs e)
{
RefreshGrid();
}
//Refresh Data Grid from external Forms
public void RefreshGrid()
{
// MySQL connection string
using (var conn = new MySqlConnection(ConnectionString()))
{
using (var mySqlDataAdapter = new MySqlDataAdapter("select * from user", conn))
{
using (var dataSet = new DataSet())
{
DataSet DS = new DataSet();
mySqlDataAdapter.Fill(DS);
dataGridView1.DataSource = DS.Tables[0];
}
}
}
}
This simply loads up the DataGridView with Usernames and passwords.
Now I need to format 2nd column to password characters, so the passwords do not show as text but formatted as *.
I have tried adding this piece of code from the 2nd resource mentioned above:
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == 1 && e.Value != null)
{
e.Value = new String('*', e.Value.ToString().Length);
}
}
This does not work - no errors show up, but I have noticed this references is set to 0.
(Note: this is what it should be)
Question:
I am confused where it is going wrong.. can somebody assist me to achieve this task?
Update (1) - Events and cell formatting not showing:
Your method is not wired to an event of GridView (thats why it has 0 references, because nothing is using your function).
The solution in the mentioned link is correct, but you should wire your method to an event in designer (right click on grid view > properties > events) and choose an event to fire up in CellFormatting event. Also dont forget to handle EditingControlShowing, but everything what you need is already written in a solution thread that you mentioned.
Why don't you modify your query to just say the below:
select username, repeat('*', length(password)) from users

Populate GridView

I cant populate grid view with the data sent to api. tell me where is the flaw. I have no idea.
protected void btnGo_Click(object sender, EventArgs e)
{
WSmyWebAPI.myWeb wsAPI = new WSmyWebAPI.myWeb();
WSmyWebAPI.OrderSearchParameters sSearchParameters = new
WSmyWebAPI.OrderSearchParameters();
DataSet ds = new DataSet();
DateTime dtmStartDate;
DateTime dtmEndDate;
dtmStartDate = Convert.ToDateTime(dpApproved.Text);
dtmEndDate = Convert.ToDateTime(dpShipped.Text);
oid = txtOrderID.Text;
opid = txtPartID.Text;
sSearchParameters.StartDate = dtmStartDate;
sSearchParameters.EndDate = dtmEndDate;
sSearchParameters.OrderID = oid;
sSearchParameters.OrderPartID = opid;
ds = wsAPI.OrderSearch(sSearchParameters);
GridView1.DataSource = ds;
GridView1.DataBind();
}
Following is a sample code. You may manipulate or adjust your code accordingly.
Make sure you have aspx code in place as well. That means the columns you want to display. Try to add
GridView1.Vissible = True
Further make sure to add a try catch block and check on SqlException. Try to go on line by line debug mode. I would suggest to display the error on a label in the webpage until your entire page is bug free. So you know where and what went wrong.
As for a suggestion, it's better to take out the connection , query parameter portion out Go click event. Add a separate method to do that. Only get the data set or data table (I recommend data table) and set it to gridview under Go click event.

DataGridView hidden column doesn't stay hidden

I have a DataGridView tied to a DataTable source. Among the data on the elements in the table is a Guid which I want to remain hidden. (It's used internally for reference, but should not be displayed.) The code I'm using to create the table is as follows:
private DataTable mEntities = new DataTable();
private System.Windows.Forms.DataGridView EntitiesGridView;
These are declared elsewhere, just showing here for reference.
private void BuildEntityTable()
{
mEntityTable.Columns.Add("id", typeof(Guid));
mEntityTable.Columns.Add("Name", typeof(string));
... (some other columns)
foreach (Foo foo in mEntities)
{
DataRow row = mEntityTable.NewRow();
row["id"] = foo.id;
row["Name"] = foo.Name;
... (rest of data)
mEntityTable.Rows.Add(row);
}
DataColumn[] entityKeys = new DataColumn[1];
entityKeys[0] = entityTable.Columns["id"];
mEntityTable.PrimaryKey = entityKeys;
EntitiesGridView.DataSource = mEntityTable.DefaultView;
EntitiesGridView.Columns["id"].visible = false;
}
So far so good. The table is created, and there's no visible "id" column. However, if I later add a new object to the table, we run into trouble. The code is almost the same:
void AddNewObject(object sender, MyArgs e)
{
Foo foo = e.Foo;
lock (mEntities)
{
mEntities.Add(foo);
}
lock (mEntityTable)
{
DataRow row = mEntityTable.NewRow();
row["id"] = foo.id;
row["Name"] = foo.Name;
... (rest of data)
mEntityTable.Rows.Add(row);
}
}
For some reason, this makes the "id" column come back. I've tried copying the EntitiesGridView.Columns["id"].visible = false; line from the previous code, but it does no good. Nothing I do after this point will make that column go away and stay gone. Any clues what I'm missing?
just write this line
datagridview1.Columns[0].visible = false;
call this event in your form_load()
private void dgv_DataBindingComplete(Object sender, DataGridViewBindingCompleteEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
dgv.Columns[3].Visible = false;
}
I have also encountered this problem, but found that you can make your datagridview changes at design time and then save the project. Run the application, then quit from the application. The dgv on the design form has now automatically changed its display. Close the form and reopen it and you will see that the columns you originally included/excluded are returned. No additional code is required for this fix.

Updating DataGridViews source programmatically?

After I change the DataGridView cell's value programmatically, the source cannot be updated. What can I do?
datagridview1.DataSource = bindingsource1;
datagridview1.Rows[0].Cells[0].Value = "1";
You need to call refresh on datagridview
datagridview1.Refresh();
If you are in edit mode then you should use EndEdit
datagridview1.EndEdit();
datagridview1.Refresh();
I think you need to do this manually. Bind the data to the gridview. Update the gridview. Select the cell that was updated, save the data back to the data and pull the data from the datasource and refresh the gridview.
You need write back the DataSet, here below my codes
private void button2_Click(object sender, EventArgs e)
{
this.Validate();
try
{
dgvArticles.CurrentRow.Cells[1].Value = txtSubject.Text;
dgvArticles.CurrentRow.Cells[2].Value = rtbBodyContent.Text;
dgvArticles.CurrentRow.Cells[3].Value = pbPrimaryPicture.Image;
dgvArticles.CurrentRow.Cells[4].Value = pbSecondaryPicture.Image;
dgvArticles.CurrentRow.Cells[5].Value = pbThirdPicture.Image;
}
catch
{
MessageBox.Show(e.ToString());
}
AccessingNetFamerDatabase anfdArticles = new AccessingNetFamerDatabase();
if (_dsArticles!= null)
{
SqlCommandBuilder _sqlCBArticles = new SqlCommandBuilder(AccessingNetFamerDatabase._sqlDataAdapter);
AccessingNetFamerDatabase._sqlDataAdapter.Update(_dsArticles.Tables[0]);
}
}
I has the same issue, was able to solve it by calling EndEdit() on the binding source.
eg
bs.EndEdit();
int x1 = data.Update(dt);
Update then returned the number of rows updated. Before the EndEdit was added it was constantly zero

Datagridview/BindingSource and sorted: add record at end of list

This will be a stupid question but I have a datagridview with a BindingSource as datasource.
The bindingSources.Datasource is a own BindingList with sort support. All this works.
But when a record will be inserted in the sorted list, then it will placed at the end of the datagridiview. After a refresh (example with the mouse click), the record will be placed on the right place.
So, I think that I forget something to implementat or call to ensure that the inserted record will be displayed directy on the right place of the datagridview.
Who can help me with a tip.
Thanks.
I have this working with the following code.
Please excuse the rough code - I'm just showing the key pieces, but I can provide a more complete example if you need.
I have a SortableBindingList _names which is bound to my DataGridView. Then on my form I have a button, with a new names added in the Click even handler. This is working fine to add the name kevin between joe and pete.
private SortableBindingList<Names> _names;
public Form1()
{
InitializeComponent();
_names = new SortableBindingList<Names>();
_names.Add(new Names() { Name = "joe" });
_names.Add(new Names() { Name = "pete" });
DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
col1.DataPropertyName = "Name";
dataGridView1.Columns.Add(col1);
dataGridView1.DataSource = _names;
}
private void button1_Click(object sender, EventArgs e)
{
_names.Add(new Names(){Name = "kevin"});
dataGridView1.Sort(dataGridView1.Columns[0], ListSortDirection.Descending);
}
public class Names
{
public string Name { get; set; }
}
So the key thing is that I sort my dataGridView after adding to the list.
I could have also provided an IComparer in my .Sort() call - the default comparer is just comparing on .ToString()
Interestingly, in my example, the following also works, when inserting the item:
private void button1_Click(object sender, EventArgs e)
{
//_names.Add(new Names(){Name = "kevin"});
_names.Insert(1, new Names() { Name = "kevin" });
// dataGridView1.Sort(dataGridView1.Columns[0], ListSortDirection.Descending);
}
Simply inserting the item at the right place is enough to make the grid display the list sorted correctly. I'm using the same SortableBindingList as you, the one shown at MartinWilley.com.
Could your problem be that you are adding rather then inserting?
Maybe try handling the BindingSource.ListChanged event?
This code snippet works very well, and fast enough for most purposes...
int iColNumber = 3; //e.g., sorting on the 3rd column of the DGV
MyBindingSource.DataSource = MyBindingList.OrderByDescending(o => o.GetType().GetProperty(MyDataGridView.Columns[iColNumber].Name).GetValue(o));

Categories