silverlight Binding from VM collection to View not working need some help
I know I am missing something here and I could use a pointer. Within a project I have an expander control when this control is clicked it makes a RIA call to a POCO within my project to retreive a second set of data. I am using the SimpleMVVM toolkit here so please let me know if I need to expand on any additional areas.
Within the xaml the expander is laid out as
<toolkit:Expander Header="Name" Style="{StaticResource DetailExpanderSytle}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Expanded">
<ei:CallMethodAction
TargetObject="{Binding Source={StaticResource vm}}"
MethodName="showWarrantNameDetail"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<StackPanel Orientation="Vertical">
<sdk:DataGrid AutoGenerateColumns="true" ItemsSource="{Binding NameResult}" AlternatingRowBackground="Gainsboro" HorizontalAlignment="Stretch" MaxHeight="200">
</sdk:DataGrid>
<local:NameContainer DataContext="{Binding}" />
</StackPanel>
</toolkit:Expander>
I am using the expression Dll coupled with Simple MVVM to get at the methods in the view model vs commands. Within the view model I have the following code
public void showWarrantNameDetail()
{
//set flags
IsBusy = true;
CanDo = false;
EntityQuery<WarrantNameDataView> query = App.cdContext.GetWarrantNameDataViewsQuery().Where(a => a.PrimaryObjectId == Convert.ToInt32(RecID));
Action<LoadOperation<WarrantNameDataView>> completeProcessing = delegate(LoadOperation<WarrantNameDataView> loadOp)
{
if (!loadOp.HasError)
{
processWarrantNames(loadOp.Entities);
}
else开发者_高级运维
{
Exception error = loadOp.Error;
}
};
LoadOperation<WarrantNameDataView> loadOperation = App.cdContext.Load(query, completeProcessing, false);
}
private void processWarrantNames(IEnumerable<WarrantNameDataView> entities)
{
ObservableCollection<WarrantNameDataView> NameResult = new ObservableCollection<WarrantNameDataView>(entities);
//we're done
IsBusy = false;
CanDo = true;
}
When I set a break on the processWarrantName I can see the NameResult is set to X number of returns. However within the view the datagrid does not get populated with anything?
Can anyone help me understand what I need to do with the bindings to get the gridview to populate? Other areas of the form which are bound to other collections show data so I know I have the data context of the view set correctly. I've tried both Data context as well as Items Source and no return? When I set a break on the code the collection is returned as follows so I can see that data is being returned. Any suggestions on what I am missing I would greatly appreciate it.
With regards to the page datacontext I am setting it in the code behind as follows:
var WarrantDetailViewModel = ((ViewModelLocator)App.Current.Resources["Locator"]).WarrantDetailViewModel;
this.DataContext = WarrantDetailViewModel;
this.Resources.Add("vm", WarrantDetailViewModel);
Thanks in advance for any suggestions.
Make ObservableCollection<WarrantNameDataView> NameResult
a public property of your ViewModel class. Your view will not be able to bind to something that has a private method scope (or public method scope, or private member scope).
//declaration
public ObservableCollection<WarrantNameDataView> NameResult { get; set }
//in the ViewModel constructor do this
NameResult = new ObservableCollection<WarrantNameDataView>();
//then replace the original line in your method with:
//EDIT: ObservableCollection has no AddRange. Either loop through
//entities and add them to the collection or see OP's answer.
//NameResult.AddRange(entities);
If processWarrantNames gets called more than once, you might need to call NameResult.Clear() before calling AddRange() adding to the collection.
Phil was correct in setting the property to public. One note I'll add is there is no AddRange property in SL or ObservableCollection class that I could find. I was able to assign the entities to the OC using the following code
private ObservableCollection<WarrantNameDataView> warrantNameResult;
public ObservableCollection<WarrantNameDataView> WarrantNameResult
{
get { return warrantNameResult; }
set
{
warrantNameResult = value;
NotifyPropertyChanged(vm => vm.WarrantNameResult);
}
}
and then within the return method
WarrantNameResult = new ObservableCollection<WarrantNameDataView>(entities);
This worked and passed to the UI the collection of data.
精彩评论