I have an data transfer object called Report. These report objects are held in an observable collection in a different class called Controller. What I am trying to do is create a view that takes data from the Report and displays that in a list.
The problem I am having is that I cannot seem to bind the view properly to the view model. I managed to get it to bind by using a value converter and returning the viewmodel that I need but the Bindings do not seem to resolve even though the view is attached.
The viewmodel that contains the Report list:
public class ReportListViewModel : Screen, IModule
{
private Controller _controller;
public Controller Controller
{
get { return _controller; }
set { _controller = value; }
}
public ReportListViewModel(Controller controller)
{
Controller = controller;
Controller.Domain.Reports.Add(new Model.Report() { Notes = "Test Data.." });
}
}
And the XAML view for it:
<Grid Background="Blue">
<StackPanel>
<StackPanel.Resources>
<local:ReportToListItem x:Key="reportToListItem" />
</StackPanel.Resources>
<ListBox Height="100" x:Name="Controller_Domain_Reports">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding Converter={StaticResource reportToListItem}}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
The value converter:
internal class ReportToListItem : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var vm = IoC.Get<ReportListItemViewModel>();
vm.Report = (Report)value;
var view = ViewLocator.GetOrCreateViewType(typeof(ReportListItemView));
ViewModelBinder.Bind(vm, view, null);
return view;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
And here are the viewmodel and view that are going to be responsible for displaying the data of the Report object.
Viewmodel:
public class ReportListItemViewModel : Screen
{
private Report _report;
public Report Report
{
get { return _report; }
set { _report = value; }
}
}
View:
<Grid>
<TextBlock Text="{Binding Report, Path=Notes}" />
</Grid>
Now I know that the view is being attached because the OnViewAttached method of the ReportListItemViewModel is triggered. I know the view is being initialed too because it’s constructor is triggered.
But the getter on the ReportListItemViewModel.Report is never called.
So what is going wrong with the Binding?
To load the view automatically with caliburn, you have to bind to Caliburn’s attached properties:
Otherwise you won’t load the corresponding view into the content control but the viewmodel itself.
Edit:
The stuff above seems to be nonsense, since the OP says the view gets created, also I think I spotted the actual problem:
If you set the binding like this:
it won’t work, since you are overwriting the path
ReportwithNotes. To access theNotesproperty inReport, you have to specify the item like this:or like this: