I have a WinForm that have a DataGridView and a ComboBox, allowing users to select a subject (from the database).
cbxSubject.DataSource = dsSched.Tables["Schedules"];
cbxSubject.DisplayMember = "Subject";
...
The DataGridView looks something like this: http://i45.tinypic.com/18gmmu.png I added the DataGridView since I don't know any other way how to get those values from the database. I used a code, something like this, to get the values:
TextBox1.Text = DataGridView1.Rows[3].Cells[1].Value.ToString();
But then I realized that it won't work anymore if there are more than 2 subjects to choose from, because the code is set to get the value on the 3rd row and the 1st cell. So even when the user changed subject, the output value (w/c are then displayed in a TextBox) will still be the same. Are there any other ways to get those values? Please help, thanks.
You can add a comboxbox this way
DataGridViewComboBoxColumn subjectsCombo = new DataGridViewComboBoxColumn();
subjectsCombo.DataPropertyName = "SubjectID";
subjectsCombo.HeaderText = "Subjects";
subjectsCombo.DataSource = dsSched.Tables["Subjects"];
subjectsCombo.ValueMember = "SubjectID";
subjectsCombo.DisplayMember = "SubjectText";
cbxSubject.Columns.Add(subjectsCombo);
I would suggest that you DONT use constants. Rather that using 3 and 1, you need to write some code to find R and C from what the user selects. It should be event driven and you need to re-set the text box on change. I'm assuming you are using an on-change event, but you haven't actually given us that information yet.
here's some pseudocode to get where im going with this
public DataGridView1_SelectionChanged(object sender, ChangedEventArgs e)
{//this might not be the right event, I'll leave it up to you to do your own homework
int R = //Get the current Selected Row;
int C = //Get the current Selected Cell/column;
TextBox1.Text = dsSched.Tables["Schedules"].Rows[R].Cells[C];
///OR YOU COULD DO SOMETHING LIKE THIS
TextBox1.Text = ((DataGridView)sender).SelectedRows[0].Cells[1].Value;
}
//Please note, this is only pseudocode, I dont like doing peoples homework for them.
This should give you a more generic idea/algorithm that you would need. Keeping in mind that this might not even be the best way to go about doing this, but Its what I would recommend based solely on the information provided to us thus far. btw, what have you tried? and can you give us some larger code examples, there might be a rather more simple mistake being made that you haven't shown us so we cant tell you about it :-)
Considering that you still haven't actually asked the correct question, because we dont know WHY you are trying to do what you have stated you are doing, I can't get any more specific than this. GIGO, you have to ask the right question in order to get the right answer.
I'll try to get some of your doubts out of the way:
I added the DataGridView since I don't know any other way how to get
those values from the database
You already have a DataSet called "dsSched" filled with database values. So, no, you don't need the DataGridView. Just fill whatever you want directly from the DataSet:
string data = dsSched.Tables["Schedules"].Rows[3].Cells[1].Value.ToString();
then I realized that it won't work anymore if there are more than
2 subjects to choose from, because the code is set to get the value on
the 3rd row and the 1st cell.
Well, I'm not sure where you are running that piece of code (TextBox1.Text = Data...), but if you are running it on the SelectedIndexChanged event of the DataGridView, then you should get data from the exact row that the user selected (or something, again, I did not understood what you are trying to do).
One thing that I suspect is that you are under the impression that the code:
TextBox1.Text = DataGridView1.Rows[3].Cells[1].Value.ToString();
...is binding the textbox to the value in the row / cell. That's not how this works - the value is retrieved once when the code is run, and then again whenever the code is run again. So you should make sure the code is run when you have to get this value.
EDIT:
I mean, how do I get the value? Like, the PrimaryKey or something?
That's the question! I'm sorry, I was probably deviating. Just set the [ValueMember][1] to the string that describes the value column of the dataset.
cbxSubject.ValueMember = "Schedule ID";
Than you access it using [SelectedValue][2], like:
int selValue = (int)(cbxSubject.SelectedValue);
Related
I'm experimenting with C#/.net/WPF all for the first time. I've created a project and set up a datasource (just a table with some sample data) and created two tableadapters named Prods and Prods1 - the latter has a filter applied in the query to return slightly different results. I've dropped both tables on my form and both dutifully display their respective data.
I thought I would then swap the data source for each. So the default generated Window_Loaded:
MSDSTest.prodtestDataSet prodtestDataSet = ((MSDSTest.prodtestDataSet)(this.FindResource("prodtestDataSet")));
// Load data into the table Prods. You can modify this code as needed.
MSDSTest.prodtestDataSetTableAdapters.ProdsTableAdapter prodtestDataSetProdsTableAdapter = new MSDSTest.prodtestDataSetTableAdapters.ProdsTableAdapter();
prodtestDataSetProdsTableAdapter.Fill(prodtestDataSet.Prods);
System.Windows.Data.CollectionViewSource prodsViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("prodsViewSource")));
prodsViewSource.View.MoveCurrentToFirst();
// Load data into the table Prods1. You can modify this code as needed.
MSDSTest.prodtestDataSetTableAdapters.Prods1TableAdapter prodtestDataSetProds1TableAdapter = new MSDSTest.prodtestDataSetTableAdapters.Prods1TableAdapter();
prodtestDataSetProds1TableAdapter.Fill(prodtestDataSet.Prods1);
System.Windows.Data.CollectionViewSource prods1ViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("prods1ViewSource")));
prods1ViewSource.View.MoveCurrentToFirst();
I now want to make the first data grid (prodsViewSource) instead display the data for the second table, and ignore the second table entirely. So, I changed that as follows:
MSDSTest.prodtestDataSet prodtestDataSet = ((MSDSTest.prodtestDataSet)(this.FindResource("prodtestDataSet")));
// Load data into the table Prods. You can modify this code as needed.
MSDSTest.prodtestDataSetTableAdapters.Prods1TableAdapter prodtestDataSetProdsTableAdapter = new MSDSTest.prodtestDataSetTableAdapters.Prods1TableAdapter();
prodtestDataSetProdsTableAdapter.Fill(prodtestDataSet.Prods1);
System.Windows.Data.CollectionViewSource prodsViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("prodsViewSource")));
prodsViewSource.View.MoveCurrentToFirst();
With the second block having been commented out.
I must be missing something fundamental - what I think I'm doing is redefining the prodtestDataSetProdsTableAddapter variable to use an instance of the prods1 table adapter, and then using that to populate the prodsViewSource grid on the form, but I end up with a blank. Where's my error?
...
Well, I posted this after beating my head against it for an hour and, minutes later, realized the FAR easier thing to do is to just change the datacontext property of the grid in question.
I would still like to understand why doing it the vastly more complicated-bordering-on-Rube-Goldbergian way didn't work, though, so if anyone can explain that, it would still be welcome.
This is my first post and I am a relative newbie regarding all things programming related. I hope you will be patient with me. I have a WPF application I am working on. My current issue is a Check ComboBox I am using. When I make selections out of the list that is pulled from a sqlite database file, the full name of the selection is displayed. I would like to change this and have a short name from the database appear in the ComboBox area while leaving the long descriptive name in the dropdown portion. I thought working with display and value member would help out, but have yet to get it working. I can get one or the other by changing the column index reference to my sqlite db. The ComboBox is a multi-select item and it needs to update as selections are made or cleared. Below is the bit of code I have that populates the ComboBox. I am unable to attach an image of the data due to low Rep numbers. Column 0 is the full descriptive name, Column 1 has the short name I am interested in displaying.
public void Fill_Modality()
{
SQLiteConnection sqliteCon = new SQLiteConnection(dbConnectionString);
try
{
sqliteCon.Open();
string Query = "Select * from Modality_list";
SQLiteCommand createCommand = new SQLiteCommand(Query, sqliteCon);
SQLiteDataReader dr = createCommand.ExecuteReader();
while (dr.Read())
{
string modname = dr.GetString(0);
Modality_Select.Items.Add(modname);
}
dr.Close();
sqliteCon.Close();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
}
Thank you for any help you may be able to provide.
Patrick
Addendum: Thank you to the folks who replied to the above post. In reviewing the suggestions provided, I have found that I didn't quite capture in detail what I was trying to accomplish.
When I click the drop down, the detailed description shows along side the checkboxes. That part is fine, no issue here. What I am looking to do is this: When the checkboxes are selected, instead of the detailed description showing in a comma delimited string in the collapsed combobox control, I would like to display the short name in a comma delimited string. The data is from a sqlite databasefile. The table is 2 columns, 0 is the detailed description, 1 is the short name.
If nothing else, I think a textbox that could be filled with the short names as the long name counter part is selected in the combobox would be fine as well. The overall goal is to have the short names available in a string for use elsewhere in the project without causing confusion by our abbreviations.
Only select what you need from the database, unless your table is only two columns, I'd avoid the astrisk. Use something like:
SELECT short_name, long_name FROM Modality_list
Then while iterating through them dr.GetString(0) would be used to access the short_name field and dr.GetString(1) would be the long_name.
Okay, how about this: You make a class with properties for short name and long name, do this for each item and put them into an array while simultaneously (within the same loop) adding the long name into the combobox. This way, they'll have the same index in their respective containers. Then, create a selected index changed event for the combobox where it uses the index of the combobox, references that index of the array, pulls the short name, and changes the text of the combobox to match.
First, I am SO sorry if the answer is out there. I've looked and looked and feel this is such a simple thing that it should be obvious.
I'm wanting to make sure only the person who added an event can modify it. Simple!
I already have a datasource that has event_added_by as a data point. It is populating a FormView.
SelectCommand="SELECT * FROM [tbl_events] WHERE ([event_ID] = #event_ID)"
And I have Page.User.Identity.Name.
How do I compare the two? I can't pull the value from the label in the FormView so I need to find another way.
if (!IsPostBack)
{
string uname = Page.User.Identity.Name;
string owner = ""// this is where I need to grab the value from dsEvents;
if (uname != owner)
{
//Send them somewhere saying they're not allowed to be here
}
}
TIA for any help!
Maybe I'm misunderstanding what you're already storing the name of who created the event in the table tbl_events and with your select all sentence you're bringing back that information also, so why don't compare that? The value returned from your select command specific column directly with your user name?
Please kindly bear with me. I need to insert the values from a lot of textboxes and combo-boxes into a DB. Now, if any of the textboxes or combo-boxes is EMPTY, I want that to be skipped, i.e. the previous value in the DB, if any, should be left untouched. Something like updating a profile. I will be so glad if you can come to my rescue.
I don't want to be writing endless
cmd.Parameters.AddWithValues(...);
...
Thank you in anticipation.
Edit:
I want a situation, for instance, if a user tries to enter new records but left some of the fields empty, I will just replace what is already in the DB with the values he/she enters. But if a field is empty, I want to leave what is already in the DB untouched choosing not to replace it with an empty value. Thanks.
I am using C# within VS2010 and the the database is MSSQL.
I would pass a null for the empty values into the db and use sql like:
Here is an example for Transact SQL for Microsoft SQL Server, using the isnull function, that checks if the first parameter is null and if sets a column to itself (ie not change it).
update the_table
set
col_x = isnull(#some_value_x, col_x),
col_7 = isnull(#some_value_y, col_y)
.
.
.
in the C# code you could use:
string some_value_x = textbox_x.Text.Trim();
if(string.IsNullOrWhitespace(some_value_x))
some_value_x = null;
I think the preferred method is to load existing values from the DB into the text boxes and then save them back into the db on the update, so users can blank out a field if they want. This will simplify your logic and be more consistent with current practices.
What about something like this:
string s;
foreach (Control cc in this.Controls)
{
if (cc is ComboBox || cc is TextBox)
{
if (!string.IsNullOrEmpty(cc.Text))
{
s = cc.Text;
//Do something with the value
}
}
I have 3 tables:
Order,
OrderStates,
OrderStateDefinition
An Order has many OrderStates which then has one OrderStateDefinition.
I have a gridview in which I am trying to display only one value inside the OrderStates collection - the latest OrderState that has been added.
I've read a little about subqueries but I'm unsure about how to go about achieving the result I want.
Sorry bout the lack of information, I had a nice picture all set up of the table structure but stackoverflow wouldn't let me upload it.
Edit -
OK I figured out how to do this. As the GridView was being populated I used the event OnRowCreated to then set the text of the field I required. To get to the control I needed I used the e.Row.FindControl.
The code for it was pretty simple in the end. I always seem to figure this stuff out when I finally ask for help.
try
{
int orderID = e.Row.RowIndex;
Order order = ShopEntities.Orders.Single(o => o.OrderStateID == orderID);
// I can now get the list of orderstates
OrderStateDefinition osd = order.OrderStates.OrderBy(o => o.Date).Last().OrderStateDefinition;
((Label)e.Row.FindControl("Label2")).Text = osd.State;
}
catch
{
}
I often find it's easier to create your own SQL that does this. the sql might be a little complex, but it's easier than mucking with the c#.