When the form loads there is a combo box where you select a GL account. Once one is selected, then I click the Get Vendor button to load the vendor information. I'm having problems with the code mainly on the form.vb. I need to populate the listview box with the vendor information and I'm not sure what I did wrong. I have referenced the payables class library etc. Getting error at vendor.count on form.vb. I haven't input the database info on Payables.DB b/c I'm not sure what it yes. Thanks.
Public Class Vendor
Dim m_VendorName As Integer
Dim m_FirstName As String
Dim m_LastName As String
Dim m_City As String
Dim m_State As String
Public Sub New()
End Sub
Public Property VendorName() As String
Get
Return m_VendorName
End Get
Set(ByVal value As String)
m_VendorName = value
End Set
End Property
Public Property FirstName() As String
Get
Return m_FirstName
End Get
Set(ByVal value As String)
m_FirstName = value
End Set
End Property
Public Property LastName() As String
Get
Return m_LastName
End Get
Set(ByVal value As String)
m_FirstName = value
End Set
End Property
Public Property State() As String
Get
Return m_State
End Get
Set(value As String)
m_State = value
End Set
End Property
Public Property City() As String
Get
Return m_City
End Get
Set(value As String)
m_City = value
End Set
End Property
End Class
Imports System.Data.SqlClient
Public Class VendorDB
Public Shared Function GetVendors() As List(Of Vendor)
Dim vendorList As New List(Of Vendor)
Dim connection As SqlConnection = PayablesDB.GetConnection
Dim selectStatement As String =
"SELECT VendorName, FirstName, Last Name, State, City " &
"FROM Vendor " &
"ORDER BY Description"
Dim selectCommand As New SqlCommand(selectStatement, connection)
Try
connection.Open()
Dim reader As SqlDataReader = selectCommand.ExecuteReader()
Dim vendor As Vendor
Do While reader.Read
vendor = New Vendor
vendor.VendorName = (reader("VendorName")).ToString
vendor.FirstName = reader("Firstname").ToString
vendor.LastName = (reader("LastName")).ToString
vendor.State = (reader("State")).ToString
vendor.City = (reader("City")).ToString
vendorList.Add(vendor)
Loop
reader.Close()
Catch ex As SqlException
Throw ex
Finally
connection.Close()
End Try
Return vendorList
End Function
End Class
Public Class GLAccount
Private m_Description As String
Public Sub New()
End Sub
Public Property Description() As String
Get
Return m_Description
End Get
Set(ByVal value As String)
m_Description = value
End Set
End Property
Imports System.Data.SqlClient
Public Class GLAccountDB
Public Shared Function GetGLAccountList() As List(Of GLAccount)
Dim accountList As New List(Of GLAccount)
Dim connection As SqlConnection = PayablesDB.GetConnection
Dim selectStatement As String =
"SELECT Description " &
"FROM GLAccounts " &
"ORDER BY Description"
Dim selectCommand As New SqlCommand(selectStatement, connection)
Try
connection.Open()
Dim reader As SqlDataReader = selectCommand.ExecuteReader()
Dim account As GLAccount
Do While reader.Read
account = New GLAccount
account.Description = reader("Description").ToString
accountList.Add(account)
Loop
reader.Close()
Catch ex As SqlException
Throw ex
Finally
connection.Close()
End Try
Return accountList
End Function
End Class
Now this is what I have referred to the payables(form and validator class)
Public Class Validator
Public Shared Function IsPresent(control As Control) As Boolean
Dim comboBox As ComboBox = CType(control, ComboBox)
If comboBox.SelectedIndex = -1 Then
MessageBox.Show(comboBox.Tag.ToString & " is a required field.")
comboBox.Select()
Return False
Else
Return True
End If
End Function
End Class
Payables
Public Class Form1
Dim vendorList As List(Of Vendor)
Dim accountList As List(Of GLAccount)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LoadComboBoxes()
End Sub
Private Sub LoadComboBoxes()
accountList = GLAccountDB.GetGLAccountList
cboAccounts.DataSource = accountList
cboAccounts.DisplayMember = "Description"
End Sub
Private Sub btnGetVendors_Click(sender As Object, e As EventArgs) Handles btnGetVendors.Click
Dim vendorList As List(Of Vendor)
Try
If Vendor.Count > 0 Then
vendorList = VendorDB.GetVendors()
Else
MessageBox.Show("All invoices were paid in full")
End If
Catch ex As Exception
End Try
End Sub
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Me.Close()
End Sub
End Class
Related
I got 2 DataTables which i open with a openFileDialog with the following columnnames: "UANR", "KostenArt", "Ueberbegriff", "Benennung", "Anzahl", "Einheit", "Einzelkosten", "SummenCode", "Kst", "AufPos", "Summenkosten".
But i only need the values for the following ones,
ReadOnly Property KostenArt As String
ReadOnly Property UANR As String
ReadOnly Property Ueberbegriff As String
ReadOnly Property Benennung As String
ReadOnly Property Anzahl As Double
ReadOnly Property Einheit As String
ReadOnly Property Einzelkosten As Double
ReadOnly Property Gesamtmenge As Integer
ReadOnly Property Summencode As String
to fill the constructor with and make a list of objects with this method:
Private Function ConvertDataTableToListOfISAACService(dt As DataTable, lst As List(Of ISAACService)) As List(Of ISAACService)
For Each row As DataRow In dt.Rows
Dim ISAAC As New ISAACService(row(KostenArt).ToString, row(UANR).ToString, row(Ueberbegriff).ToString, row(Benennung).ToString, CDbl(row(Anzahl)), row(Einheit).ToString, CDbl(row(Einzelkosten)), CInt(row(Gesamtmenge)), row(Summencode).ToString)
lst.Add(ISAAC)
Next
Return lst
End Function
Here is how i put in the datatables:
Private Sub btnDatei1_Click(sender As Object, e As EventArgs) Handles btnDatei1.Click
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
If File.Exists(OpenFileDialog1.FileName) Then
dt1 = FileGenerator.ReadFromProtectedFile(OpenFileDialog1.FileName)
dgv1.DataSource = dt1
ConvertDataTableToListOfISAACService(dt1, lst1)
End If
End If
End Sub
Private Sub btnDatei2_Click(sender As Object, e As EventArgs) Handles btnDatei2.Click
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
dt2 = FileGenerator.ReadFromProtectedFile(OpenFileDialog1.FileName)
dgv2.DataSource = dt2
ConvertDataTableToListOfISAACService(dt2, lst2)
End If
End Sub
The full code:
Public Class MainForm
Private Const KostenArt As String = "KostenArt"
Private Const UANR As String = "UANR"
Private Const Ueberbegriff As String = "Ueberbegriff"
Private Const Benennung As String = "Benennung"
Private Const Anzahl As String = "Anzahl"
Private Const Einheit As String = "Einheit"
Private Const Einzelkosten As String = "Einzelkosten"
Private Const Gesamtmenge As String = "Gesamtmenge"
Private Const Summencode As String = "Summencode"
Public dt1, dt2 As DataTable
Public lst1, lst2 As List(Of ISAACService)
Private Sub btnDatei1_Click(sender As Object, e As EventArgs) Handles btnDatei1.Click
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
If File.Exists(OpenFileDialog1.FileName) Then
dt1 = FileGenerator.ReadFromProtectedFile(OpenFileDialog1.FileName)
dgv1.DataSource = dt1
ConvertDataTableToListOfISAACService(dt1, lst1)
End If
End If
End Sub
Private Sub btnVergleich_Click(sender As Object, e As EventArgs) Handles btnVergleich.Click
'CompareDataTables()
End Sub
Private Sub btnDatei2_Click(sender As Object, e As EventArgs) Handles btnDatei2.Click
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
dt2 = FileGenerator.ReadFromProtectedFile(OpenFileDialog1.FileName)
dgv2.DataSource = dt2
ConvertDataTableToListOfISAACService(dt2, lst2)
End If
End Sub
Private Sub CompareDataTables(ByRef lst1 As List(Of ISAACService), ByRef lst2 As List(Of ISAACService))
End Sub
Private Function ConvertDataTableToListOfISAACService(dt As DataTable, lst As List(Of ISAACService)) As List(Of ISAACService)
Try
For Each row As DataRow In dt.Rows
Dim ISAAC As New ISAACService(row(KostenArt).ToString, row(UANR).ToString, row(Ueberbegriff).ToString, row(Benennung).ToString, CDbl(row(Anzahl)), row(Einheit).ToString, CDbl(row(Einzelkosten)), CInt(row(Gesamtmenge)), row(Summencode).ToString)
lst.Add(ISAAC)
Next
Return lst
Catch ex As System.ArgumentException
End Try
End Function
End Class
Think the problem is in the way you've declared lst and the signature of the ConvertDataTableToListOfISAACService method. Try something like this maybe.
Private Function ConvertDataTableToListOfISAACService(dt As DataTable) As List(Of ISAACService)
Dim lst As Zew List(Of ISAACService)
Try
For Each row As DataRow In dt.Rows
Dim ISAAC As New ISAACService(row(KostenArt).ToString, row(UANR).ToString, row(Ueberbegriff).ToString, row(Benennung).ToString, CDbl(row(Anzahl)), row(Einheit).ToString, CDbl(row(Einzelkosten)), CInt(row(Gesamtmenge)), row(Summencode).ToString)
lst.Add(ISAAC)
Next
Return lst
Catch ex As System.ArgumentException
'Do something with the exception, here.
End Try
End Function
It's also more than possible something is throwing an exception, but with your empty catch block, it's not being reported
I am trying to get the two-way combo box binding work. I have a class which serves as source for combo box and i bind the selected item/value of the combo box to data table and the data table is bound to data grid view with binding source. It works but not as i expect it to be. I want to achieve two things.
Update the Data table Grid view as soon as selection changes in the combo box (force update of data)
Add binding to Age column
Here is my code. What is the right way to do. Any help would be highly appreciated. Thanks
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Public Class Form1
Implements INotifyPropertyChanged
Public BS As New BindingSource
Public ContactBL As BindingList(Of Contacts)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim contacts As New List(Of Contacts) From {
New Contacts() With {.FirstName = "Name1", .LastName = "LName1", .Age = 50},
New Contacts() With {.FirstName = "Name2", .LastName = "LName2", .Age = 39},
New Contacts() With {.FirstName = "Name3", .LastName = "LName3", .Age = 30},
New Contacts() With {.FirstName = "Name4", .LastName = "LName4", .Age = 66}}
ContactBL = New BindingList(Of Contacts)(contacts)
ComboBox1.DataSource = ContactBL
ComboBox1.DisplayMember = "FirstName"
ComboBox1.ValueMember = "LastName"
Dim table As New DataTable("Tab1")
table.Columns.Add("FirstName", GetType(String))
table.Columns.Add("LastName", GetType(String))
table.Columns.Add("Age", GetType(Integer))
table.Rows.Add("Name3", "LName3", 30)
table.Rows.Add("Name2", "LName2", 39)
BS.DataSource = table
DataGridView1.DataSource = BS
ComboBox1.DataBindings.Add("SelectedValue", BS, "LastName", True, DataSourceUpdateMode.OnPropertyChanged)
ComboBox1.DataBindings.Add("Text", BS, "FirstName", True, DataSourceUpdateMode.OnPropertyChanged)
DataGridView2.DataSource = ContactBL
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim nr = CType(ComboBox1.SelectedItem, Contacts)
Dim NewRow = DirectCast(BS.AddNew(), DataRowView)
NewRow("FirstName") = nr.FirstName
NewRow("LastName") = nr.LastName
NewRow("Age") = nr.Age
BS.EndEdit()
End Sub
Private _FirstName As String
Public Property FirstName() As String
Get
Return _FirstName
End Get
Set(ByVal value As String)
_FirstName = value
OnPropertyChanged()
End Set
End Property
Private _LastName As String
Public Property LastName() As String
Get
Return _LastName
End Get
Set(ByVal value As String)
_LastName = value
OnPropertyChanged()
End Set
End Property
Private _Age As Integer
Public Property Age() As Integer
Get
Return _Age
End Get
Set(ByVal value As Integer)
_Age = value
OnPropertyChanged()
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Overridable Sub OnPropertyChanged(<CallerMemberName>
Optional memberName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(memberName))
End Sub
Sub BindingComplete(ByVal sender As Object, ByVal e As BindingCompleteEventArgs)
If e.BindingCompleteContext = BindingCompleteContext.DataSourceUpdate AndAlso e.Exception Is Nothing Then e.Binding.BindingManagerBase.EndCurrentEdit()
End Sub
End Class
Public Class Contacts
Implements INotifyPropertyChanged
Private _firstName As String
Private _lastName As String
Private _Age As Integer
Public Property ContactId() As Integer
Public Property FirstName() As String
Get
Return _firstName
End Get
Set
_firstName = Value
OnPropertyChanged()
End Set
End Property
Public Property LastName() As String
Get
Return _lastName
End Get
Set
_lastName = Value
OnPropertyChanged()
End Set
End Property
Public Property Age() As Integer
Get
Return _Age
End Get
Set
_Age = Value
OnPropertyChanged()
End Set
End Property
Public ReadOnly Property FullName() As String
Get
Return $"{FirstName} {LastName}"
End Get
End Property
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Overridable Sub OnPropertyChanged(<CallerMemberName>
Optional memberName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(memberName))
End Sub
End Class
Thanks
With this line of code
using (rdr as mysqldatareader = cmd.executereader())
I get an error saying rdr is not declared. When I remove the brackets so that it becomes
Using rdr As MySqlDataReader = cmd.ExecuteReader()
I get error on this line tmpObj.No = rdr("No").ToString()saying No is not a member of the project.Form.Appdata and this line
tmpObj.Template = templa8 and Template is not a member of the project.Form.AppData. Note that I have already put this: Private FPList As New List(Of AppData) at the class level, as a member. Definitely I'm doing something wrong. Any suggestions?
'THIS NEEDS TO BE AT THE CLASS-LEVEL, AS A MEMBER
'Private FPList As New List(Of AppData)
Public Class AppData
Public Sub Update()
RaiseEvent OnChange()
End Sub
Public Event OnChange()
Public FPList As New List(Of AppData)
Public IsEventHandlerSucceeds As Boolean = True
Public IsFeatureSetMatched As Boolean = False
Public FalseAcceptRate As Integer = 0
Public Sub Update()
RaiseEvent OnChange()
End Sub
Public Event OnChange()
Public FPList As New List(Of AppData)
End Class
Private Sub Me_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
Init()
StartCapture()
Dim sql As String = "SELECT * FROM new_case_file"
Using conn As New MySqlConnection("**** "), _
cmd As New MySqlCommand(sql, conn)
conn.Open()
Using (rdr As MySqlDataReader = cmd.ExecuteReader())
FPList.Clear()
While (rdr.Read())
Dim tmpObj As New AppData
tmpObj.No = rdr("No").ToString()
Dim fpBytes As Byte() = rdr("FingerPrint")
Using MemStream As New IO.MemoryStream(fpBytes)
Dim templa8 As New DPFP.Template()
templa8.DeSerialize(MemStream)
tmpObj.Template = templa8
End Using
FPList.Add(tmpObj)
End While
rdr.Close()
End Using
End Using
End Sub
You correct that error by adding the following to your AppData class
Private _No As String
Public Property No As String
Get
Return _No
End Get
Set(value as String)
_No = value
End Set
End Property
Private _Template As DPFP.Template
Public Property Template As DPFP.Template
Get
Return _Template
End Get
Set(value as DPFP.Template)
_Template = value
End Set
End Property
but that will not necessarily make your code work.
This is similar to:
https://social.msdn.microsoft.com/Forums/en-US/7b0e28b4-c1ef-49d6-8f46-11b379428052/import-from-csv-file-to-two-dimensional-array?forum=vbgeneral
but the code that Cor Ligthert suggests doesn't work even though its exactly what I need.
The code is:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim FILE_NAME As String = "C:\Users\Admin\Documents\test.csv"
Dim OutlookLines As New List(Of OutlookLine)
Dim sr As New IO.StreamReader(FILE_NAME)
Do Until sr.EndOfStream
OutlookLines.Add(New OutlookLine With {.line = sr.ReadLine})
Loop
DataGridView1.DataSource = OutlookLines
End Sub
Private Class OutlookLine
Private theLine As String
Public Property line() As String
Get
Return theLine
End Get
Set(ByVal value As String)
theLine = value
End Set
End Property
End Class
End Class
I try putting in:
.Split(","c)
after sr.ReadLine but it says "Value of type 1-D array of String cannot be converted to String"
The code above works fine but each row of the csv is scrunched into one column (obviously because I am not splitting it at the ",").
csv data:
1,2,3,4,5
6,7,8,9,0
See if this works for you:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DataGridView1.DataSource = CSVToDataTable("C:\Users\Admin\Documents\test.csv", True)
End Sub
Private Function CSVToDataTable(filePath As String, Optional hasHeaderRow As Boolean = False) As DataTable
Dim rows = IO.File.ReadAllLines(filePath).Select(Function(l) l.Split(","c))
Dim dt = New DataTable
Dim count = 0
dt.Columns.AddRange(rows.First.Select(Function(c) New DataColumn With {.ColumnName = If(hasHeaderRow, c, "Column" & Threading.Interlocked.Increment(count))}).ToArray())
For Each row In rows.Skip(If(hasHeaderRow, 1, 0))
Dim dr = dt.NewRow()
dr.ItemArray = row
dt.Rows.Add(dr)
Next
Return dt
End Function
If you wish for the line property of the OutlookLine class to be an array of string, you should define it like this:
Private Class OutlookLine
Private theLine As String()
Public Property line As String()
Get
Return theLine
End Get
Set(ByVal value As String())
theLine = value
End Set
End Property
End Class
Then this will work:
OutlookLines.Add(New OutlookLine With {.line = sr.ReadLine.Split(",")})
This is what the teacher is asking:
User selects an item from the list
The information about the item displays to the right (description, retail price, units)
The user enters a quantity and clicks Add to Cart
The subtotal, tax and grand total display
User clicks complete purchase button and a confirm order box appears. User clicks OK and the form clears for another transaction.
This is what I done:
Any Suggestions as of why I keep getting this error "Argument Index is not a valid value"
Imports System.IO
Public Class MainForm
Const strFILENAME As String = "Inventory.txt"
Dim dblTaxRate As Double = 8.75
Dim InventoryCollection As New Collection
Public Sub AddRecord(ByVal InvItem As Inventory)
Try
inventoryCollection.Add(InvItem, InvItem.InventoryNumber)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub ClearMainForm()
txtDesc.Text = String.Empty
txtRetail.Text = ""
txtOnHand.Text = ""
txtInvNumber.Text = String.Empty
End Sub
Private Sub UpdateListBox()
lstInventory.Items.Clear()
Dim InvItem As Inventory
For Each InvItem In inventoryCollection
lstInventory.Items.Add(InvItem.InventoryNumber)
Next
If lstInventory.Items.Count > 0 Then
lstInventory.SelectedIndex = 0
Else
ClearMainForm()
End If
End Sub
Private Sub SaveRecord(ByVal objInventory As Inventory)
Dim Writer As StreamWriter
Try
Writer = File.AppendText("Inventory.txt")
Writer.WriteLine(objInventory.InventoryNumber)
Writer.WriteLine(objInventory.Description)
Writer.WriteLine(objInventory.Retail.ToString())
Writer.WriteLine(objInventory.OnHand.ToString())
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim objInventory As New Inventory
Dim inventoryFile As System.IO.StreamReader
Dim blnFound As Boolean = False
Dim inventoryCollection As New Collection
Try
' Open the file.
If System.IO.File.Exists(strFILENAME) Then
End If
inventoryFile = System.IO.File.OpenText(strFILENAME)
'Enter loop and read till end of file.
Do Until inventoryFile.Peek = -1
'Read lines from file, save into Inventory object properties.
objInventory.InventoryNumber = inventoryFile.ReadLine
objInventory.Description = inventoryFile.ReadLine
objInventory.PartCost = inventoryFile.ReadLine
objInventory.Retail = inventoryFile.ReadLine
objInventory.OnHand = inventoryFile.ReadLine
'Display data in text boxes.
lstInventory.Items.Add(objInventory.InventoryNumber)
Loop
'Close the file.
inventoryFile.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub DisplayInput(ByVal InvItem As Inventory)
'Display from Collection to Label boxes
Try
txtDesc.Text = InvItem.Description
txtOnHand.Text = InvItem.OnHand.ToString()
txtRetail.Text = InvItem.Retail.ToString()
txtInvNumber.Text = InvItem.InventoryNumber
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub lstInventory_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstInventory.SelectedIndexChanged
Dim objInventory As Inventory
'See if an Item is Selected
If lstInventory.SelectedIndex <> -1 Then
'Retrieve student's data from inventoryCollection. Convert object into Inventory object.
Try
objInventory = CType(inventoryCollection.Item(lstInventory.SelectedItem), Inventory)
Catch ex As Exception
'Display error message.
MessageBox.Show(ex.Message)
Console.WriteLine("")
End Try
End If
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
'Clear Form
ClearMainForm()
End Sub
Private Sub btnExits_Click(sender As Object, e As EventArgs) Handles btnExits.Click
'Close the Form
Me.Close()
End Sub
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
Dim InvID As New Inventory
InventoryCollection.Add(InvID, InvID.InventoryNumber)
End Sub
End Class
Public Class Inventory
Private StrinvNumber As String
Private strdesc As String
Private decCost As Decimal
Private decretailPrice As Decimal
Private IntqtyOnHand As Integer
'Constructor
Public Sub New()
StrinvNumber = String.Empty
strdesc = String.Empty
decCost = 0.0
decretailPrice = 0.0
IntqtyOnHand = 0.0
End Sub
Public Property InventoryNumber() As String
Get
Return StrinvNumber
End Get
Set(ByVal value As String)
StrinvNumber = value
End Set
End Property
Public Property Description() As String
Get
Return strdesc
End Get
Set(ByVal value As String)
strdesc = value
End Set
End Property
Public Property PartCost() As Decimal
Get
Return decCost
End Get
Set(ByVal value As Decimal)
decCost = value
End Set
End Property
Public Property Retail() As Decimal
Get
Return decretailPrice
End Get
Set(ByVal value As Decimal)
decretailPrice = value
End Set
End Property
Public Property OnHand() As Integer
Get
Return IntqtyOnHand
End Get
Set(ByVal value As Integer)
IntqtyOnHand = value
End Set
End Property
End Class
Presumably the issue is here:
objInventory = CType(inventoryCollection.Item(lstInventory.SelectedItem), Inventory)
Does lstInventory contain Integer values and are those values valid indexes into inventoryCollection? I would expect not. Are those two lists supposed to correspond to each other? If so then you should be using SelectedIndex rather than SelectedItem. Probably you should have just bound the list to the ListBox in the first place and then the SelectedItem would be the object you needed already.