|
Hi,
I'm using vb 2005.
I'm making a test project to try some things out but having problem that I have a DataGridViewComboBoxColumn binded to a child table and then adding that column to a DataGridView. The column doesn't show the data from the child table until I tripple click the column. The data is the correct data though.
Details:
I have three tables that are related.
Parent table called Customers table with cust_id as PK
Orders table with order_id and foreign key being cust_id
Prices table with FK of order_id.
This is the code I used to bind the DataGridViewComboBoxColumn
Dim priceComboBoxColumn As New DataGridViewComboBoxColumn<br />
<br />
With priceComboBoxColumn<br />
<br />
.HeaderText = "price"<br />
.DataSource = priceBindingsource<br />
.DisplayMember = "price"<br />
.DataPropertyName = "price"<br />
.ValueMember = "price"<br />
.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing<br />
.Visible = True<br />
' .DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox<br />
<br />
<br />
End With<br />
<br />
dgOrders.Columns.Add(priceComboBoxColumn)
I have two pictures here to show what I mean
http://www.matcmp.ncc.edu/~steve/vb/
Any help would be greatly appreciated.
Thanks
|
|
|
|
|
It's strange that you're using a Combo to show/pick the price of a product.
Normally, a combo is used to pick from a standard list of items where the ID of an item in the list corresponds to an ID column in another table. For example, a list of team IDs and Names in one table and a schedule table, listing two teams ID's, instead of names. The combo would show you the team names (DisplayMember), but the value (ValueMember) of each name in the list returns that teams ID. This ID would be populated into the schedule table (DataPropertyName).
For this to work you need two binding sources. One bound to the schedule data and one bound to the team data. For example, there are two BindingSources, one called MasterScheduleBindingSource, which the DataGridView is bound to is bound to a table containing the data for the schedule, and a second TeamsDataBindingSource, which will be used by the combo and is bound to a table with TeamId's and names.
Dim comboColumn As New DataGridViewComboBoxColumn
With comboColumn
' Column header that shows up in the DataGridView
.HeaderText = "Home Team"
' This is the column name in the MasterScheduleBindingSource where team ID's are going to get stored.
.DataPropertyName = "HomeTeamId"
' This is the binding for the combo to it's data
.DataSource = TeamsDataBindingSource
.ValueMember = "TeamID"
.DisplayMember = "TeamName"
End With
MyDGV.Columns.Add(comboColumn)
|
|
|
|
|
I do have two binding sources.
One binding source for orders and one for prices.
I used a combobox so user can select a price from available prices but I'm open to suggestions for other controls to use.
|
|
|
|
|
SteveNY wrote: I do have two binding sources.
One binding source for orders and one for prices.
Then you've got something else set somewhere or some other code you haven't shown us screwing this up for you.
SteveNY wrote: I used a combobox so user can select a price from available prices but I'm open to suggestions for other controls to use.
Normally, a textbox does this. You usually don't find a one-to-many relationship between products and prices.
|
|
|
|
|
I think you're misunderstanding my problem.
It's not that the data isn't showing up. It's the fact that I have to click the column multiple times in order for the data to show up.
My code to initialize the column is the same as you've posted.
I made a separate demo app to show what I mean.
I put a datagridview on an empty form and in the form's load event I have this code:
<br />
<br />
Dim nameComboBoxColumn As New DataGridViewComboBoxColumn<br />
<br />
With nameComboBoxColumn<br />
<br />
.HeaderText = "names"<br />
.Items.Add("john doe")<br />
.Items.Add("jane doe")<br />
.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing<br />
<br />
<br />
End With<br />
<br />
DataGridView1.Columns.Add(nameComboBoxColumn)<br />
<br />
When the app loads the data is not shown in the column until I click the column.
|
|
|
|
|
SteveNY wrote: It's not that the data isn't showing up. It's the fact that I have to click the column multiple times in order for the data to show up.
I understand that. Since there isn't enough information to figure out what you did wrong, I supplied the template of how to do it right.
SteveNY wrote: I made a separate demo app to show what I mean.
I put a datagridview on an empty form and in the form's load event I have this code:
... When the app loads the data is not shown in the column until I click the column.
I can't duplicate the problem. There's something else you're doing that you haven't mentioned.
|
|
|
|
|
|
Your example shows the expected behavior. Since the cell doesn't have a value yet (DbNull,) one isn't selected in the ComboBox.
|
|
|
|
|
OK,
So how do I have the first item selected by default?
I have searched on the workaround since the dgvcmb doesn't have a selectedindex property but haven't found anything I have been able to use or haven't tried.
Thanks
|
|
|
|
|
The cell has to have a value that matches a Value in the data bound to the Combo.
In your example, the default cell value is DbNull, which the data in the Combo doesn't contain. Set the value of the cell to one of the values in the Combo and the combo will show the correct item.
|
|
|
|
|
try to solve the issue with the microsoft benchwork
regards,
Javed Ahmed Khan
|
|
|
|
|
HELLO
I HAVE PROGRAMMED A WINDOWS FORMS APPLICATION IN VB.NET AND TAPI
THE MAIN FORM OF THE APPLICATION IS HIDE AND EVERY TIME THE TELEPHONY RINGS THE FORM APEARS FOR 10 SECS
THE PROBLEMM IS THAT THE FORM ALWAYS ACTIVE OPENS
MAINFORM.SHOW() AND THE USER HAS TO REACTIVATE THE OTHER PROGRAMM OR FORM TO CONTINIUE HIS WORK
CAN SOMEBODY TELL ME HOW TO SHOW THE FORM WITHOUT TO MAKE IT ACTIVE
THANKS A LOT
KOSMAS
|
|
|
|
|
First, read the posting guidelines here[^], paying particular attention to point number 6. TYPING EVERYTHING IN UPPER CASE MEANS YOU'RE SCREAMING AT PEOPLE.
In order to show the form without activation, you'd have to call the Win32 API function ShowWindow . There's an example here[^].
|
|
|
|
|
I could not test it because i had no time but thanks a lot
kosmas
|
|
|
|
|
|
Was the Image that you're showing in the picturebox loaded from the very same file?? If so, you've run into a known issue where an Image object created using FromFile holds the original file open for the life of the Image object created from it. Read this[^] for a workaround.
|
|
|
|
|
The image was loaded into the picture box after reading it as binary file from the DataBase...
The link you had given is talking about when we open a file..
Which is different from what i am doing..
Here is what all i am doing...
- Connect to DB read the file
- Display it as image in picture box
- On click of a button open save file dialog and get the new destination file name and path
- save it as image on that path
Regards
Nishkarsh
|
|
|
|
|
OK, you didn't specify that in your original post.
There's a work around for this too. Basically, create your Image object from the data comming from the database, then create a NEW Image object using the first image as a source. Then you can use this copy anyway you like in your application and retain the ability to save to file.
Dim origBitmap As Bitmap ' This is the original image you created from the database
Dim copyBitmap As New Bitmap(origBitmap.Width, origBitmap.Height)
Dim g As Graphics = Graphics.FromImage(copyBitmap)
g.DrawImage(origBitmap, New Rectangle(0, 0, copyBitmap.Width, copyBitmap.Height), _
0, 0, origBitmap.Width, origBitmap.Height, GraphicsUnit.Pixel)
origBitmap.Dispose()
g.Dispose()
' The copy of the bitmap is in copyBitmap. This is the one you use in the rest of your code.
|
|
|
|
|
Thanks for the input
This is how exactly i am loading the file to the picture box
Dim ar(dataLength) As Byte<br />
<br />
myReader.GetBytes(0, 0, ar, 0, dataLength)<br />
myReader.Close()<br />
<br />
Dim b As New MemoryStream(ar)<br />
<br />
picView.Image = Image.FromStream(b)
How exactly can i implement ur suggestion
Another question
Can you please explain why can i NOT directly save the image when it is already ain the picture box in this case
Regards
Nishkarsh
|
|
|
|
|
Forget the picturebox. All it's there for is to show an image. You're not telling the picturebox to save anything. You're actually calling the Save method of the Image object that's been assigned to the Image property of the picturebox.
The reason has to do with GDI+ and it's annoying habit of locking source bits. You're getting the "general" error because the original source for the Image object no longer exists. Copying the bitmap you made gets around this little problem.
In your code, your creating a Bitmap object from a stream of bytes, but not really hanging onto that Bitmap anywhere in your code. All you have to do is change the code a bit:
Dim ar(dataLength) As Byte
myReader.GetBytes(0, 0, ar, 0, dataLength)
myReader.Close()
Dim b As New MemoryStream(ar)
Dim origBitmap As Bitmap = Image.FromStream(b)
... ' The rest of the code to copy the Bitmap goes here.
... ' Then you can tell the picturebox to show the image.
picView.Image = copyImage
|
|
|
|
|
Thanks a loot for helping me understand the issue... it worked
Regards
Nishkarsh
|
|
|
|
|
I am currently building a simple database access class. I have a function GetCourse which I want to get a course object from the database.
I could specify it like this:
<br />
public static function GetCourse(byval courseid as integer) as Course<br />
An alternative would be:
<br />
public static function GetCourse(byval courseid as integer, byref course as Course) as Boolean<br />
the two methods are only different by how they return the values. the first would return Nothing when it couldnt find a course (throw an exception or return Nothing when a database error occurred). the second function would return false when it couldnt find a course and true when it could (either throwing exceptions or returning false in the case of a db error) and it would assign the course details to the course parameter.
The calling method would either check for Nothing in the case of the first function or check for true/false in the case of the second function to indicate that the course could be found.
I would like to hear peoples opinions on which function you would prefer and why. Or if there is a better alternative
Thanks!
|
|
|
|
|
The first method is better. You have the option of either returning Nothing or throwing an exception. A custom exception would probably be ideal, depending on your requirements of course. Your calling code would just have to check to see if the return was Nothing instead of a Boolean.
|
|
|
|
|
Im not sure of your point. With the second method you also have the option of throwing an exception or returning false (instead of nothing).
the calling methods would be something like this (if the functions didnt handle their own exceptions
1.
<br />
try<br />
course = GetCourse(courseid)<br />
catch<br />
'error handle<br />
end try<br />
if course is nothing then<br />
' do something<br />
else<br />
'do something else<br />
end if<br />
2.
<br />
try<br />
if GetCourse(courseid, course) then<br />
' do something<br />
else<br />
' do something else<br />
end if<br />
catch<br />
' error handle<br />
end try<br />
theyre essentially the same as far as i can tell
|
|
|
|
|
Why use an extra Boolean that does that exact same thing as checking the return for an object?
|
|
|
|