Связывание Caliburn.Micro, по-видимому, не разрешается в представлении модели - PullRequest
3 голосов
/ 20 января 2012

У меня есть объект передачи данных с именем Report. Эти объекты отчета хранятся в наблюдаемой коллекции в другом классе под названием Controller. Я пытаюсь создать представление, которое берет данные из Report и отображает их в списке.

Проблема, с которой я столкнулся, заключается в том, что я не могу правильно привязать вид к модели вида. Мне удалось заставить его связываться, используя конвертер значений и возвращая нужную модель представления, но привязки, кажется, не разрешаются, даже если представление присоединено.

Модель представления, содержащая список Report:

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.." });
    }
}

И представление XAML для него:

<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>

Значение преобразователя:

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();
    }
}

А вот модель и представление, которые будут отвечать за отображение данных объекта Report.

ViewModel:

public class ReportListItemViewModel : Screen
{
    private Report _report;
    public Report Report
    {
        get { return _report; }
        set { _report = value; }
    }
}

Вид:

<Grid>
    <TextBlock Text="{Binding Report, Path=Notes}" />
</Grid>

Теперь я знаю, что представление присоединяется, потому что OnViewAttached метод ReportListItemViewModel запущен. Я знаю, что представление тоже инициализируется, потому что его конструктор запущен.

Но геттер на ReportListItemViewModel.Report никогда не вызывается.

Так что же не так с Связыванием?

1 Ответ

11 голосов
/ 20 января 2012

Чтобы автоматически загрузить представление с помощью caliburn, вам необходимо привязать к прикрепленным свойствам Caliburn:

<ContentControl cal:View.Model="{Binding ...}"/>

В противном случае вы не загрузите соответствующий вид в элемент управления содержимым, а саму модель представления.

Редактировать:

Все вышеперечисленное кажется бессмысленным, так как ОП говорит, что представление создается, также я думаю, что я обнаружил реальную проблему:

Если вы установите привязку следующим образом:

<TextBlock Text="{Binding Report, Path=Notes}" />

это не сработает, поскольку вы перезаписываете путь Report с помощью Notes.Чтобы получить доступ к свойству Notes в Report, необходимо указать элемент, подобный следующему:

<TextBlock Text="{Binding Report.Notes}" />

или как этот:

<TextBlock Text="{Binding Path=Report.Notes}" />
...