datagridview formatting not applying - vb.net

In my form load event I am setting the defaultcellstyle formats. They are not taking hold anyone know why? None of the formatting that is expected in the code after I bind the datatable to the grid is getting done even though the code steps through it
Private Sub frmADRORD_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'wire the delegate function for incoming updates
AddHandler m_helper.DataUpdate, AddressOf UpdateGridInvoker
'bind the visual grid with the binding source
Me.datagridADRORD.DataSource = dsGridView
'get data from helper class
m_dt = m_helper.GetTable()
'bind the binding source with datatable
Me.datagridADRORD.DataSource = m_dt
**'after data loaded, auto resize columns and format
Me.datagridADRORD.AutoResizeColumn(DataGridViewAutoSizeColumnMode.AllCellsExceptHeader)
With Me.datagridADRORD.ColumnHeadersDefaultCellStyle
.BackColor = Color.Gold
.Alignment = DataGridViewContentAlignment.MiddleCenter
.WrapMode = DataGridViewTriState.True
.Font = New Font(Control.DefaultFont, FontStyle.Bold)
End With
Me.datagridADRORD.Columns("ADR Price").DefaultCellStyle.Format = "##.##"
For Each row As DataGridViewRow In Me.datagridADRORD.Rows
row.Cells("ORD Price").DataGridView.DefaultCellStyle.FormatProvider = Globalization.CultureInfo.GetCultureInfo(m_helper.CurrCultureInfoStr(row.Cells("Currency").Value))
Next
Me.datagridADRORD.Columns("Currency Price").DefaultCellStyle.Format = "##.####"
Me.datagridADRORD.Columns("Difference").DefaultCellStyle.Format = "##.##"**
End Sub

You have to set the ValueType of the column, and "##.##" doesn't seem to work (in C# anyway).
This works in C#:
this.dataGridView1.Columns["Column3"].ValueType = typeof(Double);
this.dataGridView1.Columns["Column3"].DefaultCellStyle.Format = "N2";
Also the data being bound has to actually be of some numeric type (I presume it is, but can't be sure from your code snippet).
You'll have to translate typeof() to equivalent VB.NET, and I don't know whether the difference between "##.##" and "N2" is a control thing (in which case you'll need to change it) or a language thing (in which case you won't).

Related

What is the correct event to use to catch a new row when the user has finished editing?

I need to add several bits of data to my record such as created date and createdby when a user adds a new row in a datatable.
I am looking for the correct event on the bindingsource to catch this so i can add the information then save the record before the user moves onto the next row.
C# seems to have a RowEditEnding event on the datagrid but a)i'm not using C# and b) I can see from searching that its better to work on the datasource, which in this case is a bound datagrid so i presume i should be looking at the bindingsource object but there is not an obvious event to choose.
I think need something like currentchanged with condition if isdirty then...
Please can someone point me in the right direction here.
thanks
john
this seems to work
Private Sub TblOppQuoteDetailBindingSource_CurrentChanged(sender As Object, e As EventArgs) Handles TblOppQuoteDetailBindingSource.CurrentChanged
If sender.current IsNot Nothing Then
If sender.current.IsNew Then
Dim nr As DataRowView = sender.current
nr.Item("OppQuoteID") = 2
nr.Item("Created") = Now
nr.Item("CreatedBy") = G_UserName
ElseIf sender.current.isedit Then
Dim nr As DataRowView = sender.current
nr.Item("OppQuoteID") = 2
nr.Item("Updated") = Now
nr.Item("UpdatedBy") = G_UserName
End If
End If
End Sub
is this the correct way?

DataGridView bound to DataTable is not showing

I am trying to show a DataGridView in a form that is bound to a DataTable, but it's not showing up. I was doing this using a C1TrueDBGrid and that was working...I decided to switch to using a DataGridView due to some complications with the TrueDBGrid. Can anyone help me figure out why nothing is showing?
In the form I declare these:
Public binData As DataSet
Friend WithEvents dgvData As System.Windows.Forms.DataGridView
The binData is filled with tables created via a separate calculation routine. Then this is the form load event:
'create a tab page and add data grid view for every table in the set
For i = 0 To binData.Tables.Count - 1
Dim tabPage As C1.Win.C1Command.C1DockingTabPage = New C1.Win.C1Command.C1DockingTabPage
tabPage.Text = binData.Tables(i).TableName
tabContent.TabPages.Add(tabPage)
Dim dgvData = New System.Windows.Forms.DataGridView
Dim binding As New BindingSource
binding.DataSource = binData.Tables(i)
With dgvData
.Dock = DockStyle.Fill
.AllowUserToOrderColumns = False
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.DefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomLeft
.DataSource = binding
.AutoGenerateColumns = True
End With
tabPage.Controls.Add(dgvData)
Next 'DataTable In binData.Tables
When the form loads, the tab pages are there and labeled as expected, but they look empty (no table).
I did try instead setting the DataSource to the DataSet called binData (as opposed to a specific table), and then setting dgvData's DataMember property to the name of the specific table I want to display in it...that made no difference.
Note: I need to be able to do this programmatically at runtime as opposed to using the visual designer because I do not know the exact number of grids I need until the form loads with a particular dataset - the dataset it gets can have a different number of tables depending on what the user wants.
Here's some rough code to add dgvs to a flow panel:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Static dgvCount As Integer
dgvCount += 1
Dim dgvNew As New DataGridView
dgvNew.Width = DataGridView1.Width
dgvNew.Height = DataGridView1.Height
dgvNew.Name = "dgv" & dgvCount
' clone other properties as need
FlowLayoutPanel1.Controls.Add(dgvNew)
Debug.Print(FlowLayoutPanel1.Controls(FlowLayoutPanel1.Controls.Count - 1).Name)
End Sub
Starts with one dgv - DataGridView1 as the model for properties. Anchoring is not working in the flow panel so some custom code may be need to change width.
Flow panel doesn't scroll so may not be the best choice - look into TableLayout as a possibility. TabControl is another option.
OK, well it turns out there was nothing wrong with what I was doing. The issue turned out to be in one line of code that has nothing to do with binding the DGV's datasource or anything.
ComponentOne has a control called a ThemeController in which you can set themes for your forms and the controls within. I had a line of code to set the theme for dgvData to my default application theme (which sets visual style and details regarding colors, fonts, etc.). For whatever reason, THAT was rendering my grid non-visible. I will be logging a ticket with them.

Rowstate remains always unchanged even if data changes

I have a datagrid bound to Oracle database. I would like to update my fields through the gridview. I used Update method which was not successful. After advanced diagnose I came up with the following observations when executing this code.
Private Sub MainGridView_ColumnChanged(ByVal Sender As Object, ByVal e As DataColumnChangeEventArgs) Handles DataTable.ColumnChanged
e.Row.AcceptChanges()
e.Row.EndEdit()
DataTable.AcceptChanges()
BindingSource.EndEdit()
End Sub
When I change a row, the value changes in memory. It's checked using break points and Watchs ( e.Row.Item("Field") has a different value )
e.Row.RowState remains Unchanged in the watch in all the steps of the excution.
Here is the code for binding the data to the database:
Public Sub FillForm()
SQL = "SELECT * FROM ARCHITECT.ARCH_TASKS"
Command = New OracleCommand(SQL, Connection)
DataAdapter = New OracleDataAdapter(Command)
DataSet.Tables.Add(DataTable)
DataAdapter.Fill(DataTable)
BindingSource.DataMember = "Table1"
BindingSource.DataSource = DataSet
Me.GridControl1.DataSource = BindingSource
End Sub
Here is a video preview Preview
Is there anything else I should take into consideration ?
Appreciate your help.

Binding Source changes current item when datagrid looses focus

I have a WinForm with 6 DataGridViews in VB.Net 2010, each with their own binding source. I have one additional main DataGridView that controls what is in the other grids. This is the only grid that allows a new record to be added. All others are controlled programmatically. The main grid binding source is bound to an observable collection of objects, with an additional binding source for one of the class objects from the collection.
My issue is that when I click on the new row in the main grid, everything clears as it is suppose to by instantiating a new single class object, but when I tab off of the grid or click or anything else, the binding source for the grid resets its current item to the first item in the grid. If I set the single object binding source to the new instantiated object, it clears the first item in the collection as well. This does not happen on any other screens where we use DataGridViews bound to observable collections. What am I missing?
Sample code of grid click implementation
Private Sub dgvReports_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvReports.CellClick
If e.RowIndex < 0 Or dgvReports.SelectedRows.Count < 0 Then
Exit Sub
End If
If Not dgvReports.Rows(e.RowIndex).IsNewRow Then
objReport = dgvReports.Rows(e.RowIndex).DataBoundItem
objReport.SerializeToDB()
intSelIndex = e.RowIndex
objReport = objReport.Deserialize()
If objReport.MsgObject.ErrMsg > "" Then
objReport.MsgObject.DisplayErrMsg()
End If
btnDelete.Enabled = True And Not blnReadOnly
Else
objReport = New RBL.Report
objReport.GlobalID = Guid.NewGuid.ToString
intSelIndex = e.RowIndex
btnDelete.Enabled = False
End If
' The following 3 lines of code causes the first record in grid to be reset
' but works in other implementations
'If objReport IsNot Nothing Then
'bsReport.DataSource = objReport
'End If
btnApply.Enabled = False
UpdateReportObjects()
End Sub
Private Sub UpdateReportObjects()
Dim objRprt As RBL.Report = Nothing
If dgvReports.SelectedRows.Count = 1 Then
objRprt = dgvReports.SelectedRows(0).DataBoundItem
End If
' Set all local observable collections to Report properties
If objReport.GlobalID = objRprt.GlobalID Then
RptFieldLst = objReport.ReportFields
RptTableLst = objReport.TableList
DisplayFieldLst = objReport.DisplayFields
SortFldLst = objReport.SortList
Else
' Instantiate new collections and set to new Report object properties
RptTableLst = New RBL.ReportTables()
RptFieldLst = New RBL.ReportFields()
DisplayFieldLst = New RBL.ReportFields()
NonDisplayFieldLst = New RBL.ReportFields()
SortFldLst = New RBL.ReportSortOrders()
objReport.TableList = RptTableLst
objReport.ReportFields = RptFieldLst
objReport.DisplayFields = DisplayFieldLst
objReport.SortList = SortFldLst
End If
End Sub
Problem has been discovered, and as usual, the finger points back at myself. DataSource for the observable collection's binding source and the single item's binding source where being set to the same variable object, the single class object.
Problem solved.

vb.net. How do I bind dataset to DataRepeater?

I am looking for a vb.net example of how to bind a dataset/datatable to data repeater and have the data elements bound to the columns of the dataset/datatable?
Thanks
At first I thought you wanted a web repeater, but from your comments I realized you meant Microsoft.VisualBasic.PowerPacks.DataRepeater.
I need some more info from you to give the most helpful sample code (see below).
The basic steps of using a DataRepeater are:
1) Install the Visual Basic Power Packs 3 Link
2) Open a VB.net Winforms project and drag a DataRepeater to your form
3) Add a new Dataset to your project via Add->New Item menu
4) In the design window, set up columns as desired
5) Open the Data Sources window from Data->ShowDataSources menu
6) With your form in design mode, go to the Dataset in the Data Sources window and use the dropdown box next to the table name to select "Details"
7) Drag the table to top section of the DataRepeater control (on your form). The table fields should now be listed on your DataRepeater. You can move them around.
8) At runtime, you can load the Datset and the DataRepeater will automatically reflect the data changes. No .Databind is required
ex.
me.DataSet1.Tables(0).Columns.Add(New String() {"John", "Doe", "Accountant"}
or
myDataAdapter.Fill(me.DataSet1.Tables(0))
Do you get tripped up on any of those steps?
Edit:
From what I have seen, it looks like DataRepeater is meant to be used in situations were you add/map the datatable to the DataRepeater at design-time. Then all you have to do is fill the datatable at run-time and the DataReader shows the data automatically.
If you really want to add the table/controls to the DataRepeater at run time, here's an example I coded for you. It assumes a form named Form3 with a DataRepeater named DataRepeater1 and a button named Button1...
Public Class Form3
''Set up demo DataSet/DataTable
Const FRUIT_COL As String = "Fruit"
Const COLOR_COL As String = "Color"
MyDataSet = New DataSet
MyDataSet.Tables.Add("MyTable")
With MyDataSet.Tables(0)
.Columns.Add(FRUIT_COL, GetType(System.String))
.Columns.Add(COLOR_COL, GetType(System.String))
End With
''Populate the DataTable with sample data. You would be loading from SQL
With MyDataSet.Tables(0)
.Rows.Add(New String() {"Apple", "Red"})
.Rows.Add(New String() {"Orange", "Orange"})
.Rows.Add(New String() {"Banana", "Yellow"})
End With
''These objects would normally be created automatically if you added DataTable to DataRepeater at design-time
FruitLabel = New Label
FruitTextBox = New TextBox
ColorLabel = New Label
ColorTextBox = New TextBox
With FruitLabel
.AutoSize = True
.Location = New Point(10, 20)
.Name = "FruitLabel"
.Text = FRUIT_COL
End With
With ColorLabel
.AutoSize = True
.Location = New Point(10, 60)
.Name = "FruitLabel"
.Text = FRUIT_COL
End With
With FruitTextBox
.Location = New Point(50, 20)
.Size = New Size(60, 15)
.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.MyDataSet.Tables(0), FRUIT_COL, True))
End With
With ColorTextBox
.Size = New Size(60, 15)
.Location = New Point(50, 60)
.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.MyDataSet.Tables(0), COLOR_COL, True))
End With
''Add the controls that will be displayed for each row in DataTable
With DataRepeater1
.ItemTemplate.Controls.Add(FruitLabel)
.ItemTemplate.Controls.Add(FruitTextBox)
.ItemTemplate.Controls.Add(ColorLabel)
.ItemTemplate.Controls.Add(ColorTextBox)
End With
''Run-time population of DataRepeater from your DataTable
DataRepeater1.DataSource = MyDataSet
DataRepeater1.DataMember = MyDataSet.Tables(0).TableName
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Example of how you can add additional rows with form elements
With MyDataSet.Tables(0)
.Rows.Add(New String() {"Grapes", "Green"})
End With
End Sub
End Class
Now that you have seen the code, I hope you don't use it :)
I suggest you either set up your DataSet structure at design-time or use a different control to display your data.
Here's a link that has lots of information about the typical way to use DataRepeater:
Link
Final Edit
The user's last bug was a case-sensitivity issue. The string "Text" in the following line of code must be capitalized to match the control's property name. I recommend creating a const for "Test" to avoid this typo.
[ControlName].DataBindings.Add(New System.Windows.Forms.Binding("Text", [DataTable], [Column Name], True))
Dim data As DataSet
DataRepeater1.DataSource = data
DataRepeater1.DataBind()