I'm trying to have a combobox field in my WPF datagrid with the options in the combobox coming from a SharePoint list. I have managed to get the options into the combo box OK, but it's not listening to the SelectedItemBinding setting and the values are showing as blank for each item. The data for the DataGrid is also coming from a SharePoint list but it has been cast to an ObservableCollection. Here's the XAML:
<DataGrid Name="dgVendorSchedule" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3"
AutoGenerateColumns="False"
SelectionChanged="dgVendorSchedule_SelectionChanged"
EnableRowVirtualization="True"
IsReadOnly="False"
>
<DataGrid.Columns>
<DataGridTextColumn Header="Title" Binding="{Binding title, Mode=TwoWay}" />
<!-- <DataGridTextColumn Header="Vendor" Binding="{Binding vendorName, Mode=TwoWay}" />-->
<DataGridComboBoxColumn x:Name="cmbVendor"
Header="Vendor"
SelectedValueBinding="{Binding vendorName}"
DisplayMemberPath="Title">
</DataGridComboBoxColumn>
<DataGridTextColumn Header="Billing Date" Binding="{Binding billingDate, Mode=TwoWay}" />
<DataGridTextColumn Header="Payment" Binding="{Binding paymentTitle, Mode=TwoWay}"/>
<DataGridTextColumn Header="Invoice" Binding="{Binding invoiceTitle, Mode=TwoWay}"/>
</DataGrid.Columns>
</DataGrid>
and here's the code behind:
var lstVendors = (from i in colVendorSched.AsEnumerable<SP.ListItem>()
select new vendor
{
vendorName = ((SP.FieldLookupValue)i["Vendor"]).LookupValue,
billingDate = ((DateTime)i["Billing_x0020_Date_x0020__x0028_"]).ToLocalTime(),
itemID = (int)i["ID"],
title = (string)i["Title"],
//using the ? operator to trap null values on the lookup field before retrieving the lookupvalue property
invoiceTitle = i["Invoice"] == null ? "" : ((SP.FieldLookupValue)i["Invoice"]).LookupValue,
paymentTitle = i["Payment"] == null ? "" : ((SP.FieldLookupValue)i["Payment"]).LookupValue
});
var lstVendorList = (from i in colVendorList.AsEnumerable<SP.ListItem>()
select new
{
Title = i["Title"],
ID = i["ID"]
});
cmbVendor.ItemsSource = lstVendorList;
ObservableCollection<vendor> obsVendors = new ObservableCollection<vendor>(lstVendors);
dgVendorSchedule.ItemsSource = obsVendors;
I'm fairly new to working with WPF and frankly this binding stuff is making my head hurt. I'd appreciate any pointers.
EDIT: for posterity... The solution turned out to be creating a class for the vendorItem and having that be a member of the vendor class like so:
public class vendor
{
public VendorItem vendorName {get; set;}
public DateTime billingDate {get; set;}
public int itemID {get; set;}
public string title {get; set;}
public string invoiceTitle {get; set;}
public string paymentTitle { get; set; }
}
public class VendorItem
{
public string Title { get; set; }
public int ID { get; set; }
}
This made it possible to set the selectedValuePath, and have the binding work properly. Here's the working XAML for the column:
<DataGridComboBoxColumn x:Name="cmbVendor"
Header="Vendor"
SelectedValueBinding="{Binding vendorName.ID}"
SelectedValuePath="ID"
DisplayMemberPath="Title" >
</DataGridComboBoxColumn>