I have a small problem. DataGridViewComboBoxColumn displays a value from ValueMember and not from DisplayMember. The grid works fine and when I select something from this column I see the DisplayMember value, but when the focus gets lost, the grid shows a ValueMember. I have this code combo box column:
statusCBoxColumn.DataSource = dt 'datatable with two fields StatusId and StatusText
statusCBoxColumn.DisplayMember = "StatusText" 'is type NVarchar
statusCBoxColumn.ValueMember = "StatusId" 'is type Int
Can anybody help me?
Edit: I solved this in the following way:
Private Sub dgv_CellFormatting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgv.CellFormatting
If (dgv.Columns(e.ColumnIndex).Name = "statusCBoxColumn") Then
If e.Value & "" > "" Then
Dim s1 As String = e.Value
e.Value = GetData("Select StatusText from Status where ID = " & e.Value).ToString()
End If
End If
End Sub
But I don't think that it's the best solution...
Have you set datapropertyName of the comboboxcolumn and added the column to datagridview? You've to write
statusCBoxColumn.DataPropertyName = "StatusId";
and add the column like
datagridview1.Columns.Add(statusCBoxColumn);
I had the same problem.
The "statusID" for me is long.
I made it by system.type.gettype("System.Int64")
That gave the same behaviour.
When changing it to Int32, the behaviour was OK.
So it was à mismatch between valuemember type and datagridview type.
I know this is a 10 years old question, but I was having same problem and I found out that according to MSDN :
When the DataSource property is set to a string array, the ValueMember property does not need to be set because each string in the array will be used as a valid display string and as a valid underlying value.
Try this one I've also have a problem on displaying value member,hope it will work.
For index = 0 To cbo.Items.Count - 1
cbo.SelectedIndex = index
MessageBox.Show(CType(cbo.SelectedValue, String))
Next
What i had used is:
Dim jm As Integer
jm = CType(cmbCategory.SelectedValue, String)
MsgBox(jm)
e.Value = GetData("Select to_char(StatusId) , StatusText from Status where ID = " & e.Value).ToString()
Related
I am trying to set up a DataGridView in VB.Net where a single column, called "Supplier" acts as a TextBox with an AutoCompleteSource to help users with entering data. This is the code I put together to attempt to accomplish this:
Private Sub OrderData_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles orderData.EditingControlShowing
Dim colIndex = orderData.SelectedCells.Item(0).ColumnIndex
Dim headerText As String = orderData.Columns(colIndex).HeaderText
If headerText.Equals("Supplier") Then
Dim autoText As TextBox = TryCast(e.Control, TextBox)
If autoText IsNot Nothing Then
autoText.AutoCompleteMode = AutoCompleteMode.SuggestAppend
autoText.AutoCompleteSource = AutoCompleteSource.CustomSource
autoText.AutoCompleteCustomSource = FillTextBoxData("supplier_name", "suppliers")
End If
End If
End Sub
I kind of works. Unfortunately it adds AutoCompletes to every single editable column in the table, instead of just the "Supplier" column (column index 2).
What do I need to do to fix this?
EDIT: I modified the code a bit to try and fix the issue, and it kind of worked. If I don't selected the "Supplier" column first, then the other columns to not contain an AutoComplete. However if I go from the "Supplier" column to another column, then it contains an AutoComplete. How do I fix this?
When you do
Dim headerText As String = orderData.Columns(2).HeaderText
If headerText.Equals("Supplier") Then
That will be always true, since you are always getting the col 2 header no matter what cell is selected, you need to add that, something like
Dim colIndex = orderData.SelectedCells.Item(0).ColumnIndex
then you can use your code
Dim headerText As String = orderData.Columns(colIndex).HeaderText
Also add an Else clause to the If headerText.Equals("Supplier") Then statement. In the Else portion add the line autoText.AutoCompleteMode = AutoCompleteMode.None
I am using Grid from devExpress to display some data from database, I also implemented RepositoryItemLookUp because I needed to see some values in my column as dropdowns and here is the code:
`Dim riLookup As New RepositoryItemLookUpEdit()
riLookup.NullText = String.Empty
DataTableDobTableAdapter.FillDob(Me.DsOrders.DataTableDob)
riLookup.DataSource = Me.DsOrders.DataTableDob
riLookup.ValueMember = "ID"
riLookup.DisplayMember = "TITLE"
riLookup.BestFitMode = DevExpress.XtraEditors.Controls.BestFitMode.BestFitResizePopup
GridView1.Columns("Code").ColumnEdit = riLookup`
Here is the photo of that what I am talking about:
I'm wondering how can I handle this repositoryitemlookupedit so if whatever is choosen there I might change value of another column from N to D as I highlighted in a image.
Maybe I can write condition in my appereance-> format condition section.
Whatever I need to change another columns value if something is choosen from this repositoryitemlookupedit, whatever I'm really struggling with this because I've never used before v.b neither devexpress.
Thanks guys
Cheers!
AFTER ALEX HELP:
I put a breakpoint there to check what is e.NewValue and I saw it is acctually ID from database, because I choosed MCI which has ID 1000097 and when breakpoing hitted I catch that Id but with suffix :"D" at the end.. why is that?
You could handle the RepositoryItemLookupEdit.EditValueChanging event.
Just add an event handler to your existing code:
Dim riLookup As New RepositoryItemLookUpEdit()
riLookup.NullText = String.Empty
DataTableDobTableAdapter.FillDob(Me.DsOrders.DataTableDob)
riLookup.DataSource = Me.DsOrders.DataTableDob
riLookup.ValueMember = "ID"
riLookup.DisplayMember = "TITLE"
riLookup.BestFitMode = DevExpress.XtraEditors.Controls.BestFitMode.BestFitResizePopup
GridView1.Columns("Code").ColumnEdit = riLookup
'Add this line:
AddHandler riLookup.EditValueChanging, AddressOf repItem_EditValueChanging
Now just handle the event and do your logic to set the "N/D" column:
Private Sub repItem_EditValueChanging(sender As Object, e As ChangingEventArgs)
If e.NewValue > -1 Then 'any ID given => "N"
GridView1.SetRowCellValue(GridView1.FocusedRowHandle, GridView1.Columns(6), "D")
Else
GridView1.SetRowCellValue(GridView1.FocusedRowHandle, GridView1.Columns(6), "N")
End If
End Sub
(I assumed column 6 from your screenshot).
P.S.: One thing that I couldn´t find in your code but which is neccessary to get a repository item to work properly is to add it to your GridView RepositoryItems collection like:
GridControl1.RepositoryItems.Add(riLookup)
Since i needed to disable (grey out) some items inside a ListBox, i'm using a Custom control that can be found here:
Here is my current code:
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
dtp.Columns.Add("key")
dtp.Columns.Add("value")
PopulateDataTable(dtp, "myTxt")
_dataView = New DataView(dtp)
'Custom ListBox
List1.ValueMember = "key"
List1.DisplayMember = "value"
List1.DataSource = _dataView
'Legacy ListBox
List2.ValueMember = "key"
List2.DisplayMember = "value"
List2.DataSource = _dataView
UpdateLanguageMenu()
End Sub
Private Function PopulateDataTable(dt As DataTable, resTxt As String)
Using sw As New StringReader(My.Resources.ResourceManager.GetObject(resTxt))
Do
Dim line As String = sw.ReadLine
If line Is Nothing OrElse line.Trim = String.Empty Then Exit Do
Dim strArr() As String
strArr = line.Split(",")
Dim row As DataRow = dt.NewRow()
row("key") = strArr(0)
row("value") = strArr(1)
dt.Rows.Add(row)
Loop
sw.Close()
End Using
End Function
List1 is the Custom ListBox and List2 is the ListBox that comes with VS2012E.
I don't need List2, it's only there to test,
and at runtime, in List2 i get all my values loaded correctly, instead in List1 i get System.Data.DataRowView in all rows..
The strange thing is that, my txt i'm loading is like:
00A1,MyValue1
00A2,Myvalue2
00A3,MyValue3
I have also a Label, and when selecting items on the ListBox i have code to change the Label.Text to List.SelectedValue that is the first part before the comma.
And it get displayed in the label. Only items inside the Custom ListBox are not being displayed.
Populating List1 manually, instead using a DataTable, is working.
And since i'm a beginner i can't locate the problem.
I think your problem has to do with this line: string displayValue = GetItemText(item); in the control. This takes for granted that all items are strings. In your case it is a datarowview hence the result (drv.toString would return something like that). You need to convert "item" into a drv and set display value to be drvItem("value" or "key") instead. So it is basically not your code that is the problem, it is the control.
Actually... After reading the code in the control and not on the code project site, I realised that this line:
displayValue = GetItemText(item);
Doesn't even exist. It is exchanged with
item.ToString()
Which pretty much proves my theory.
Right, how to fix.
In:
protected override void OnDrawItem(System.Windows.Forms.DrawItemEventArgs e)
You have this:
object item = this.Items[e.Index];
What you have to do is to convert item into a DataViewRow and assign value to a variable, something like this:
DataViewRow dvrItem = (DataViewRow)item;
String displayText = dvrItem("key"); or String displayText = dvrItem("value");
Then change all these:
e.Graphics.DrawString(item.ToString(), e.Font, SystemBrushes.GrayText, e.Bounds);
Into:
e.Graphics.DrawString(displayText, e.Font, SystemBrushes.GrayText, e.Bounds);
I have a gridview0 in a multiview and when I click select on a row I have the GridView0_SelectedIndexChanged sub change to a different view in the multiview, which has a different gridview1 but the same datasource as gridview0. This is when it errors out and it displays the invalid column name error, with the column name being the datakeyname of the first gridview0 row that was selected.
The first image is the view of gridview0, and the second is the error that occurs when I click select. Thanks!
image one http://img291.imageshack.us/img291/9221/gridview0.jpg
image two http://img188.imageshack.us/img188/6586/gridview1.jpg
Protected Sub GridView0_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView0.SelectedIndexChanged
Dim ISTag As String = GridView0.SelectedDataKey.Value.ToString
Dim type As String = getTypeMethod(ISTag)
filterText.Text = type
If (type.Equals("Computer")) Then
InventoryComputer.SelectCommand = "SELECT * FROM T_Computer WHERE ISTag = " & ISTag
MultiView1.ActiveViewIndex = 8
End If
End Sub
Adding a new datasource and setting the where to the original gridview worked.
I have a DataGridView with two DataGridViewComboBoxColumns. I want to use the selected item in the first column to trigger a re-population of the items in the second column, on a per-row basis.
Here's the code I have so far. "addlInfoParentCat" identifies the first column, and currentRow.Cells.Item(1) is the DataGridViewComboBoxCell that I want to re-populate. ExtEventAdditionalInfoType is a type I defined that contains the string/value pairs.
Private Sub dgvAdditionalInfo_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvAdditionalInfo.CellValueChanged
Dim currentCell As DataGridViewCell
currentCell = Me.dgvAdditionalInfo.CurrentCell
If Not currentCell Is Nothing Then
If currentCell.OwningColumn.DataPropertyName = "addlInfoParentCat" Then
Dim parentTypeID As Integer = currentCell.Value
Dim currentRow As DataGridViewRow = Me.dgvAdditionalInfo.CurrentRow
Dim subtypeCell As DataGridViewComboBoxCell = currentRow.Cells.Item(1)
Dim theChildren As New List(Of ExtEventAdditionalInfoType)
theChildren = Custom_ExtEventAdditionalInfoType.GetChildrenOfThisParentOrderByTypeName(parentTypeID)
subtypeCell.DataSource = Nothing
subtypeCell.DataSource = theChildren
subtypeCell.DisplayMember = "ExtEventAdditionalInfoTypeDescr"
subtypeCell.ValueMember = "ID_ExtEventAdditionalInfoType"
End If
End If
End Sub
Basically what I see is that the binding works great the first time around. When I select a item in the first column, it populates the items correctly in the second. I can add rows to the DataGridView and repeat the process.
The problem comes when I try to change the first-column item after the second column has already been bound. I get an endless string of dialog boxes with the following:
System.ArgumentException: DataGridViewComboBoxCell value is not valid.
Any idea why this is happening? Thanks in advance!
UPDATE CodeByMoonlight's suggestion appears to work.
I clear the DataGridViewComboBoxCell's value before re-binding:
....
subtypeCell.DataSource = Nothing
subtypeCell.Value = Nothing 'here's the change
subtypeCell.DataSource = theChildren
....
Well, it looks like as soon as you remodify the first combo's value, you're invalidating the binding and datasource you used to populate the second combo, causing all the errors.