WPF Set SelectedValue for ComboBox on page reload - wpf

I have a ComboBox that is created when the page is initialised
Dim CategoryCombo As New CustomControl.ComboCBx
With CategoryCombo
.Name = "MaintTypes_CatCombo"
End With
RegisterControl(MaintenanceTypes_Grid, CategoryCombo)
vToolBar.Items.Add(CategoryCombo)
vToolBar.Items.Add(TS_Separator)
and added to the toolbar
It is populated in the load event
Dim CatCombo As CustomControl.ComboCBx = MaintenanceTypes_Grid.FindName("MaintTypes_CatCombo")
With CatCombo
.IsNewRecord = False
.Width = 200
.ItemsSource = ReturnCategories.DefaultView
.SelectedValuePath = "ID"
.DisplayMemberPath = "Name"
.SelectedIndex = 0
End With
If the user navigates to another page and returns the selected value is returned to the selected index of 0. I can grab the last selected value before leaving the page but cannot find a way to set .SelectedValue when the page reloads
Data comes from
Private Function ReturnCategories() As DataTable
Try
CatDT = New DataTable
With CatDT.Columns
.Add("ID", GetType(Integer))
.Add("Name", GetType(String))
End With
With CatDT.Rows
.Add(0, "Select Category")
End With
Using vService As New Service1Client
strSQL = "SELECT Category_ID as 'ID', Category_Name as 'Name' FROM Maintenance_Categories "
strSQL += "WHERE Management_ID = " & Management_ID
strSQL += " ORDER BY Category_Name"
Dim DS As DataSet = vService.ReturnDataSetHAS(strSQL)
For Each Row As DataRow In DS.Tables(0).Rows
With CatDT.Rows
.Add(Row("ID"), ReturnText(Row("Name")))
End With
Next
End Using
Return CatDT
Catch ex As Exception
EmailError(ex)
Return Nothing
End Try
End Function
Any ideas?
Thanks

Found a workaround - return the index from the DataTable and set the .SelectedIndex of the ComboBox with that
In case someone has deleted the selected item prior to returning to the page check the row exists first
Dim vIndex As Integer = 0
If Not CurrentCategory = 0 Then
Dim vRow As DataRow = CatDT.Select("ID = '" & CurrentCategory & "'").FirstOrDefault()
If Not vRow Is Nothing Then
vIndex = CatDT.Rows.IndexOf(vRow)
End If
End If
With CatCombo
.IsNewRecord = False
.Width = 200
.ItemsSource = ReturnCategories.DefaultView
.SelectedValuePath = "ID"
.DisplayMemberPath = "Name"
.SelectedIndex = vIndex
End With

Related

Fetching data from database into text boxes

I have designed a SQL Server database app in which I fetch data from database and then insert in text boxes. I use a function to fetch data in data table from database and then I populate textboxes. I have to use this coding again and again:
If Dt.Rows.Count > 0 Then
TxtCust_Id.Text = Dt.Rows(0).Item(0)
TxtCust_City.Text = Dt.Rows(0).Item(1)
TxtCust_Area.Text = Dt.Rows(0).Item(2)
Else
TxtCust_Id.Text = String.Empty
TxtCust_City.Text = String.Empty
TxtCust_Area.Text = String.Empty
End if
Text boxes names changes according to query tables. My question is. Is it possible to make a function or procedure to populate data in text boxes from datatable using loops or any other method? Thanks in advance.
Shared Function ExecuteSelectDt(ByVal SelectCommand As String) As DataTable
Cmd = New SqlClient.SqlCommand
Sda = New SqlDataAdapter
' Dt = New DataTable
Try
DBConnection() ' Database connection details
Sda = New SqlDataAdapter(SelectCommand, Con)
Dim dt2 As New DataTable
Sda.Fill(dt2)
CloseConnection()
Return dt2
Catch ex As Exception
CloseConnection()
MsgBox(ex.Message)
Return dt
End Try
End Function
Private Sub TxtCust_Name_Leave(sender As Object, e As EventArgs) Handles TxtCust_Name.Leave
SQuery = "select Cust_Id, Cust_City, Cust_Area from TBLCustommers where Cust_Name= '" & TxtCust_Name.Text & "'"
Dt = Nothing
Dt = BM_Class_Liberary.SQLSereverDB.ExecuteSelectDt(SQuery)
If Dt.Rows.Count > 0 Then
TxtCust_Id.Text = Dt.Rows(0).Item(0)
TxtCust_City.Text = Dt.Rows(0).Item(1)
TxtCust_Area.Text = Dt.Rows(0).Item(2)
Else
TxtCust_Id.Text = String.Empty
TxtCust_City.Text = String.Empty
TxtCust_Area.Text = String.Empty
End if
End Sub
'create and populate list
dim txtBoxes as new List(of TextBox)();
for each ctrl as Control in Form.Controls
if ctrl.GetType() Is GetType(TextBox) then txtBoxes.Add(ctrl)
next
' then do this when you get DataTable
dim theRow as DataRow = dt.Rows(0); ' whatever logic you have to getting needed row
for each col as DataColumn in dt.Columns
' use system.linq
txtBoxes.First(function(tb) tb.Name = col.ColumnName).Text = theRow(col.ColumnName).ToString()
next
Note, when theRow(col.ColumnName) is DBNull.Value, ToString will return string.Empty, which is fine because .Text can't have Nothing
Also, I used First because I did it with the premise that each column has text box.
Or, using the dictionary. Even better, I think
'create and populate dictionary
dim txtBoxes as new Dictionary(of string, TextBox)();
for each ctrl as Control in Form.Controls
if ctrl.GetType() Is GetType(TextBox) then txtBoxes.Add(ctrl.Name, ctrl)
next
' then do this when you get DataTable
dim theRow as DataRow = dt.Rows(0); ' whatever logic you have to getting needed row
for each col as DataColumn in dt.Columns
txtBoxes(col.ColumnName).Text = theRow(col.ColumnName).ToString()
next

How to get pre-selected combo box value from combo box?

Here as you can see I'm not using combox_click because it is declared above and the current one is another function to be called without clicking, here my question is how do I get the pre-selected value from the combo box without clicking on the box?
Public Sub ComDep_Change()
Dim sQuery As String
Dim oRS As New ADODB.Recordset
Dim rsPR As New ADODB.Recordset
Dim dateFormat As String
Dim sPONO As String
Dim sPOAmt As String
'oRS.Open "po_receiveable", PRCnn, adOpenDynamic, adLockOptimistic
combVal = ComDep.List(ComDep.ListIndex)
If Not combVal = "ALL_DEPT" And frmMain.OptLatestCN.Value = True Then
'MsgBox ("Works")
dateFormat = "#" + CStr(Day(Now)) + "/" + CStr(Month(Now)) + "/" + CStr(Year(Now) - 3) + "#"
sQuery = "select * from CN_Request_Header where dept = '" & combVal & "' and requestdate >= " & dateFormat & ""
' sQuery = "Select PO_No, PO_Requestor, PO_Req_Dept, PO_Status, PO_Approval_M, PO_Approval_GM, PO_Approval_D, PO_HRApproval, VC_No, TH_Sup_Inv, PO_HR_Rmk, PO_Req_Date, PO_SupplierName, PO_OverallAmt from PR_INFO where PO_Req_Dept = '" & combVal & "'"
' MsgBox ("Result" & sQuery)
rsPR.Open sQuery, PRCnn, adOpenDynamic, adLockOptimistic
lvwCreditNote.ListItems.Clear
Do While Not rsPR.EOF
Set listitem = frmMain.lvwCreditNote.ListItems.Add
With listitem
.Text = CStr(Trim(rsPR!requestID))
.SubItems(1) = Trim(rsPR!requestID)
.SubItems(2) = Format(CStr(rsPR!requestdate), "dd-mmm-yy")
.SubItems(3) = Trim(rsPR!createby)
.SubItems(4) = Trim(rsPR!dept)
.SubItems(5) = Trim(rsPR!reqstatus)
If IsNull(rsPR!custName) Then
.SubItems(6) = ""
Else
.SubItems(6) = Trim(rsPR!custName)
End If
If IsNull(rsPR!cnamt) Then
.SubItems(7) = "0.00"
Else
.SubItems(7) = Format(rsPR!cnamt, "#,###,##0.00")
End If
You would get the currently SELECTED element in a combobox
by using the SELECTEDINDEX Property
If nothing is selected then you get the value -1 returned to you.
If something is selected it will be in the range 0 to Combox.Count - 1
To get the text for the selected item
You could use something like...
Dim SelIndex as Integer
Dim SelText As String
'
SelIndex = MyCombobox.SelectedIndex
If (SelIndex >= 0) AND (SelIndex <= MyCombobox.Count - 1) Then
SelText = MyCombobox.List(Index)
Else
'Nothing was selected in the combobox
End If

SQL Server database not getting updated

I am using the following code, but database is not getting updated:
Dim update As New SqlCommand("Update FAGR SET FAGRN=#FAGRN,FAGRU=#FAGRU WHERE FAGRC=#FAGRC", connection)
update.Parameters.Add(New SqlParameter("#FAGRC", SqlDbType.NChar, 3))
update.Parameters.Add(New SqlParameter("#FAGRN", SqlDbType.NVarChar, 50))
update.Parameters.Add(New SqlParameter("#FAGRU", SqlDbType.NChar, 3))
Dim i As Integer
i = 0
Do While i < DataGridView1.Rows.Count
Try
update.Parameters(0).Value = DataGridView1.Rows(i).Cells(0).ToString
update.Parameters(1).Value = DataGridView1.Rows(i).Cells(1).ToString
update.Parameters(2).Value = DataGridView1.Rows(i).Cells(2).ToString
vartemp1 = update.ExecuteNonQuery()
i=i+1
Catch ex As Exception
MsgBox("Exception:" & vbCrLf & ex.Message)
Finally
Me.Close()
End Try
Loop
'IN A SIMILAR INSERT QUERY THE FIRST ROW OF GRID IS INSERTED IN DATABASE. THE OTHER RECORDS ARE NOT INSERTED BUT ALSO NO ERROR IS SHOWN.
First, make sure you're referring to the right columns:
Dim fagrc As DataGridViewColumn = DataGridView1.Columns("FAGRC")
Dim fagrn As DataGridViewColumn = DataGridView1.Columns("FAGRN")
Dim fagru As DataGridViewColumn = DataGridView1.Columns("FAGRU")
DataGridViewCell.ToString do not return the cell value. From reflector:
Public MustInherit Class DataGridViewCell
Public Overrides Function ToString() As String
Return String.Concat(New String() {"DataGridViewCell { ColumnIndex=", Me.ColumnIndex.ToString(CultureInfo.CurrentCulture), ", RowIndex=", Me.RowIndex.ToString(CultureInfo.CurrentCulture), " }"})
End Function
End Class
Do it like this:
Dim id As String = Nothing
For Each row As DataGridViewRow In DataGridView1.Rows
If (Not row.IsNewRow) Then
id = row.Cells(fagrc.Index).Value.ToString()
If (String.IsNullOrEmpty(id)) Then
Throw New ApplicationException("FAGRC missing.")
Else
update.Parameters(0).Value = id
update.Parameters(1).Value = row.Cells(fagrn.Index).Value.ToString()
update.Parameters(2).Value = row.Cells(fagru.Index).Value.ToString()
If (update.ExecuteNonQuery() <= 0) Then
Throw New ApplicationException("Could not update FAGRC with value '" & id & "'.")
End If
End If
End If
Next
Try to use the ForEach
'IN A SIMILAR INSERT QUERY THE FIRST ROW OF GRID IS INSERTED IN
DATABASE. THE OTHER RECORDS ARE NOT INSERTED BUT ALSO NO ERROR IS
SHOWN.
For Each dataGridViewRow As DataGridViewRow In DataGridView1.Rows
If dataGridViewRow.Index = 0 Then 'hint: this is your temporary textbox
Update.Parameters(0).Value = dataGridViewRow.Cells(0).ToString()
'Others Stuff
'vartemp1 = Update.ExecuteNonQuery()
Exit For
End If
Next
Hope it will helps.

WPF ListBox - refresh

I have a ListBox populated by a DataTable - adding items, moving items all work but delete doesn't - it reflects in the DataTable but clears all items from the ListBox unless it is reloaded as part of a SelectionChanged event.
I have tried Listbox.Items.Refresh and setting the ItemsSource to Nothing and re-assigning back to the DataTable.
Any ideas?
Thanks
Private Sub Reports_BalanceSheet_NominalListBox_Delete(NomLB As String, DT As DataTable)
Try
Dim LB As ListBox = Reports_BalanceSheet_Grid.FindName(NomLB)
If LB.SelectedIndex = -1 Then
AppBoxValidation("No item has been selected for deletion!")
Exit Sub
End If
Dim FR() As DataRow = DT.Select("ID = " & LB.SelectedValue, Nothing)
Dim CatID As Integer = 0
For Each row As DataRow In FR
CatID = row("CatID")
row.Delete()
Next
DT.AcceptChanges()
Dim vDV As New DataView(DT)
vDV.RowFilter = "FormID = " & FormID & " AND CatID = " & CatID
vDV.Sort = "Position"
DT = vDV.ToTable
vDV = Nothing
Dim i As Integer = 0
For Each row As DataRow In DT.Rows
row("Position") = i
i += 1
Next
With LB
.ItemsSource = DT.DefaultView
.DisplayMemberPath = "Name"
.SelectedValuePath = "ID"
End With
Catch ex As Exception
EmailError(ex)
End Try
End Sub
Turns out the clue was 'unless it is reloaded as part of the SelectionChanged event'
added this to the end and it all works perfectly :-)
Have you ever noticed that you can spend hours going round in circles and the moment you post the problem you figure it out?
Dim MainLB As String = NomLB.Replace("Nominal", "")
Reports_BalanceSheet_ListBox_IndexChanged(MainLB, NomLB, DT)
and that runs
Private Sub Reports_BalanceSheet_ListBox_IndexChanged(ByVal MainLB As String, ByVal NominalLB As String, ByVal NomDT As DataTable)
Try
Dim LB As ListBox = Reports_BalanceSheet_Grid.FindName(MainLB)
If LB.SelectedIndex = -1 Then
Exit Sub
End If
Dim NomLB As ListBox = Reports_BalanceSheet_Grid.FindName(NominalLB)
If NomLB Is Nothing Then
Exit Sub
End If
If LB.SelectedValue Is Nothing Then
Exit Sub
End If
If LB.SelectedValue.GetType.Name Is Nothing Then
Exit Sub
End If
If LB.SelectedValue.GetType.Name <> "DataRowView" Then
Dim CatID As Integer = LB.SelectedValue
Dim DT As DataTable = NomDT.Copy()
Dim vDV As New DataView(DT)
vDV.RowFilter = "CatID = " & CatID & " AND FormID = " & FormID
vDV.Sort = "Position"
DT = vDV.ToTable
vDV = Nothing
With NomLB
.ItemsSource = DT.DefaultView
.SelectedValuePath = "ID"
.DisplayMemberPath = "NomName"
.Items.Refresh()
End With
End If
Catch ex As Exception
EmailError(ex)
End Try
End Sub

WFP - odd behaviour when opening new tab

The user can select from a DataGrid either by double clicking on the row, or selecting the row and clicking a button.
Using the first method the new page is initialised but the loaded event is not fired.
Using the second method the new page is initialised, the old one fires the unloaded event and the new one fires the loaded event and the new tab opens.
As both the click and doubleclick events are firing the same sub I can't figure out why one works and the other doesn't - when not in debug the new tab is formed using the first method and when clicked the loaded event is then fired, but this doesn't show in debug.
Private Sub Reports_BalanceSheets_EditRecord(sender As Object, e As RoutedEventArgs)
Try
NewRecord = False
Dim DGV As CustomControl.DGVx = Reports_BalanceSheets_Grid.FindName("Reports_BalanceSheets_DGV")
If DGV.SelectedItems.Count = 1 Then
Dim row As System.Data.DataRowView = DGV.SelectedItems(0)
FormID = row("ID")
Dim vName As String = row("Name")
Dim vTab As CustomControl.STC_Tabx = Application.Current.MainWindow.FindName("Reports_BalanceSheetTab")
Dim TabControl As CustomControl.STCx = Application.Current.MainWindow.FindName("AccountingReports_TabControl")
Dim vImageSource As String = ReturnImageAsString("Profit_Loss.png", 16)
If vTab Is Nothing Then
Dim ReportsBalanceSheetFrame As New Frame
Dim Tab As New CustomControl.STC_Tabx
With Tab
.Name = "Reports_BalanceSheetTab"
.Header = " Edit " & vName & " "
.CloseButtonVisibility = DevComponents.WpfEditors.eTabCloseButtonVisibility.Visible
.TabToolTip = "Edit " & vName
.ImageSource = vImageSource
.Content = ReportsBalanceSheetFrame
End With
AddHandler Tab.Closing, AddressOf TabControl_TabClosing
Dim vGrid As Grid = Application.Current.MainWindow.FindName("MainGrid_Website")
RegisterControl(vGrid, Tab, Tab.Name.ToString)
TabControl.Items.Add(Tab)
Dim BalanceSheet As New Reports_BalanceSheet_Page
ReportsBalanceSheetFrame.NavigationService.Navigate(BalanceSheet)
TabControl.SelectedItem = Tab
Else
vTab.Close()
Dim ReportsBalanceSheetFrame As New Frame
Dim Tab As New CustomControl.STC_Tabx
With Tab
.Name = "Reports_BalanceSheetTab"
.Header = " Edit " & vName & " "
.CloseButtonVisibility = DevComponents.WpfEditors.eTabCloseButtonVisibility.Visible
.TabToolTip = "Edit " & vName
.ImageSource = vImageSource
.Content = ReportsBalanceSheetFrame
End With
AddHandler Tab.Closing, AddressOf TabControl_TabClosing
Dim vGrid As Grid = Application.Current.MainWindow.FindName("MainGrid_Website")
RegisterControl(vGrid, Tab, Tab.Name.ToString)
TabControl.Items.Add(Tab)
Dim BalanceSheet As New Reports_BalanceSheet_Page
ReportsBalanceSheetFrame.NavigationService.Navigate(BalanceSheet)
TabControl.SelectedItem = Tab
End If
ElseIf DGV.SelectedItems.Count > 1 Then
AppBoxValidation("You can only select one item at a time to edit!")
Else
AppBoxValidation("You must select an item to edit!")
End If
Catch ex As Exception
EmailError(ex)
End Try
End Sub
Adding e.Handled resolved the issue

Resources