Привязать команду к кнопке внутри ListView с помощью Caliburn.Micro

Я пытаюсь создать что-то вроде интерфейса с вкладками MDI, поэтому у меня есть панель навигации (Listbox) слева, а ContentPresenter справа.

У меня есть ShellViewModel, который имеет BindableCollection на нем под названием AvailAbleScreens, и мне удалось успешно привязать к этому списку с помощью DataView: ListView:

<ListView x:Name="AvailableScreens">
    <ListView.ItemTemplate>
        <DataTemplate>
            <WrapPanel>
                <BulletDecorator />
                <Button x:Name="DisplayView">
                    <TextBlock Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" />
                </Button>
            </WrapPanel>
        </DataTemplate>
    </ListView.ItemTemplate>

Теперь проблема заключается в том, что, хотя имя кнопки установлено правильно, я не могу заставить Command fire для меня. В классе MdiViewModel у меня есть следующий код для этой кнопки:

public bool CanDisplayView()
{
    return true;
}

public void DisplayView()
{
    MessageBox.Show("Hello");
}

Все образцы Caliburn.Micro работают с привязкой через соглашения к свойству x: Name, но если я удалю Text = "{Binding}", он перестает работать, поэтому я подозреваю, что этот способ привязки данных не работает для sub -моделей?

В любом случае, Shell ViewModel на данный момент довольно прост:

ShellViewModel
 * AvailableScreens
    -MdiViewModel1
    -MdiViewModel2
 * CurrentActiveScreen

Любая идея, как я буду делать это с Caliburn.Micro? Роб Эйзенберг предложил мне в Twitter. Возможно, мне захочется начать с Caliburn.Micro, прежде чем отправиться в полноценную платформу Caliburn.

Ответ 1

К сожалению, мы не можем автоматически применять соглашения к содержимому DataTemplates. Причина этого в том, что мы не можем перехватить механизм создания шаблона WPF/Silverlight. Чтобы обойти это, у вас есть несколько вариантов:

  • Не используйте соглашения внутри DataTemplates; Используйте явные привязки и вместо Message.Attach

  • Извлеките все DataTemplates в UserControls, которые будут заменять соглашения в UserControl. Это хорошая идея для больших шаблонов, но утомительных для маленьких.

  • Используйте прикрепленное свойство Bind.Model в корневом каталоге UIElement DataTemplate, например, Bind.Model="{Binding}". Это приведет к тому, что соглашения будут привязаны к DataTemplate. К сожалению, это может не совсем правильно работать из-за некоторых ошибок в Caliburn. Он работает в Caliburn.Micro. Я надеюсь, что скоро эта ошибка исчезнет.