This question is locked. New answers and comments are not allowed.
I have a GridView which contains combo boxes in the cells whereby these combo boxes are populated from web service results. I have tried two different methods, and neither of which I have been successful at getting to work or am unsure if the approach is correct.
Method 1:Using Static Resources
In this method, I created classes that pull the data from the web service and then set them as static resources in the MainPage.xaml
public class EmployeeList { private ESWeb.ESWebServiceSoapClient _es; private ESWeb.ESErrorInfo _err; private ESWeb.EmployeeListResults _EmployeeList; public EmployeeList() { _es = new ESWeb.ESWebServiceSoapClient(); _es.EmployeeListCompleted += new EventHandler<ESWeb.EmployeeListCompletedEventArgs>(_es_EmployeeListCompleted); _es.EmployeeListAsync("", "", "", "", "", ""); } private void _es_EmployeeListCompleted(object sender, ESWeb.EmployeeListCompletedEventArgs e) { _EmployeeList = e.Result; } public ESWeb.EmployeeListRow[] List { get { return _EmployeeList.RowSet.Rows; } } }<UserControl.Resources> <local:EmployeeList x:Key="EmpList" ></local:EmployeeList> <local:MarketSegment x:Key="MarketSeg"></local:MarketSegment> </UserControl.Resources> <Grid x:Name="LayoutRoot"> <telerik:RadGridView x:Name="uxEmployeeList" ItemsSource="{Binding Source={StaticResource EmpList}, Path=List}" AutoGenerateColumns="false" > <telerik:RadGridView.Columns> <telerik:GridViewDataColumn Header="Employee ID" DataMemberBinding="{Binding Employee.ID}" /> <telerik:GridViewDataColumn Header="Employee Name" DataMemberBinding="{Binding Employee.EmployeeName}" /> <telerik:GridViewDataColumn Header="Position" DataMemberBinding="{Binding Position.Value}" /> <telerik:GridViewDataColumn Header="Head Count" DataMemberBinding="{Binding Headcount.NumericValue}" /> <telerik:GridViewDataColumn Header="FTE" DataMemberBinding="{Binding FTE.NumericValue}" /> <telerik:GridViewDataColumn Header="Employee Type" DataMemberBinding="{Binding EmpType.ID}" /> <telerik:GridViewDataColumn Header="Pay Type" DataMemberBinding="{Binding PayType.Value}" /> <telerik:GridViewComboBoxColumn UniqueName="MarketSegment" Header="Market Segment" /> <telerik:GridViewDataColumn Header="Job Title" DataMemberBinding="{Binding JobTitle.Value}" /> <telerik:GridViewDataColumn Header="Position Start Date" DataMemberBinding="{Binding PositionStartDate.Value}"> </telerik:GridViewDataColumn> <telerik:GridViewDataColumn Header="Position End Date" DataMemberBinding="{Binding PositionEndDate.Value}" /> <telerik:GridViewDataColumn Header="Location" DataMemberBinding="{Binding Location.Value}" /> <telerik:GridViewDataColumn Header="Transferred To" DataMemberBinding="{Binding TransferredTo.Value}" /> </telerik:RadGridView.Columns> </telerik:RadGridView> </Grid> With this method, it appears that the Async web service calls are held up in the thread pool and not executed until the UI portion is completed. Unfortunately, the List binding path is called before the web service returns, and a null exception is thrown. I even tried to put the async web service calls in a backgroundworker thread, but that still didn't work.
So, I tried method 2:
In method 2, I am not binding the grid declaratively, but rather in the code behind. The grid view seems to be timed correctly with the completion of the web service, but the combo boxes within the grid are not. I have considered doing the binding within the RowLoaded event, but am not sure if this is the right approach for what I am trying to do. (i.e. as opposed to PreparingCellForEdit, etc)
public MainPage2() { _es = new ESWeb.ESWebServiceSoapClient(); _es.EmployeeListCompleted += new EventHandler<ESWeb.EmployeeListCompletedEventArgs>(_es_EmployeeListCompleted); _es.EmployeeListAsync("", "", "", "", "", ""); _es.MarketSegmentsCompleted += new EventHandler<ESWeb.MarketSegmentsCompletedEventArgs>(_es_MarketSegmentsCompleted); _es.MarketSegmentsAsync(); InitializeComponent(); } private void _es_MarketSegmentsCompleted(object sender, ESWeb.MarketSegmentsCompletedEventArgs e) { Debug.WriteLine("Market segments completed"); _marketSegmentList = e.Result; } private void _es_EmployeeListCompleted(object sender, ESWeb.EmployeeListCompletedEventArgs e) { Debug.WriteLine("Market employee list completed"); _empList = e.Result; uxEmployeeList.ItemsSource = _empList.RowSet.Rows; uxEmployeeList.RowLoaded += new EventHandler<Telerik.Windows.Controls.GridView.RowLoadedEventArgs>(uxEmployeeList_RowLoaded); } void uxEmployeeList_RowLoaded(object sender, Telerik.Windows.Controls.GridView.RowLoadedEventArgs e) { //Apply binding here } The concern that I have is that the content of each combobox within the grid view need to contain the same data (and these combo boxes can sometimes be very large), so I would like to keep the memory usage as low as possible and re-use where I can.
So, with all that background, what is the best approach? Static resource binding or on code behind?
If code behind, what is appropriate manner to accomplish this?
If resource bound, how can I get around the thread queuing problem?
Thanks for your help!