使用具有分层视图模型结构的caliburn.micro

时间:2013-05-19 16:22:17

标签: c# mvvm binding caliburn.micro

在一个项目中,我使用caliburn.micro作为MVVM框架。

现在我有一个大型视图模型用于主 - 详细信息视图。

它是分层构建的。

举个例子:

我有ComputerView ComputerViewModel。这里的一切都很好。

现在,此ComputerViewModel包含ObservableCollection<HardwareComponentViewModel>

HardwareViewModel没有附加View,它只是用于保存数据。 Caliburn在这里没有正确设置Binding。 (我无法使用x:name获取Binding

直到现在,这都没问题,因为我可以使用“正常”绑定方式。 现在,我需要在ActionMessage

中为网格添加HardwareComponentViewModel

为了更清楚我的意思,这里有完整的XAML来重现它

<UserControl x:Class="DemoApplication.Views.ComputersView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:cal="http://www.caliburnproject.org"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:s="clr-namespace:System;assembly=mscorlib"
             d:DesignHeight="300"
             d:DesignWidth="300"
             mc:Ignorable="d">
    <Grid>
        <Grid.Resources />
        <Grid.RowDefinitions>
            <RowDefinition Height="10*" />
            <RowDefinition Height="2*" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>

        <Border HorizontalAlignment="Stretch"
                BorderBrush="Transparent"
                BorderThickness="0">
            <ScrollViewer HorizontalContentAlignment="Stretch"
                          Background="Yellow"
                          BorderBrush="Transparent"
                          BorderThickness="0"
                          CanContentScroll="True"
                          HorizontalScrollBarVisibility="Auto"
                          VerticalScrollBarVisibility="Auto">
                <ListView x:Name="Computers"
                          HorizontalContentAlignment="Stretch"
                          Background="Red"
                          BorderThickness="0">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <Border Background="Transparent"
                                    BorderBrush="Transparent"
                                    BorderThickness="0">
                                <ListView HorizontalContentAlignment="Stretch"
                                          Background="Black"
                                          ItemsSource="{Binding HardwareComponents}">
                                    <ListView.ItemTemplate>
                                        <DataTemplate>
                                            <Border Background="Aquamarine"
                                                    BorderBrush="DarkGray"
                                                    BorderThickness="1">
                                                <Grid Background="Lime" cal:Message.Attach="[Event Click] = [Action Expand($dataContext)]">
                                                    <Grid.RowDefinitions>
                                                        <RowDefinition Height="20" />
                                                    </Grid.RowDefinitions>
                                                </Grid>
                                            </Border>
                                        </DataTemplate>
                                    </ListView.ItemTemplate>
                                </ListView>
                            </Border>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </ScrollViewer>
        </Border>
    </Grid>
</UserControl>

更新

1。 在UserControl上尝试了cal:Bind.Model="{Binding}",但没有效果 Took them from this question here

2。 在Grid中我尝试过: cal:Message.Attach="[Event Click] = [Action Expand]"但不起作用

3。 我现在添加了Logging并获得了

未应用行动惯例:展开无可操作元素。

但我不知道它试图告诉我什么。也许没有任何动作可以应用于Grid?

4。 现在将它绑定到网格内的按钮,这是有效的。 作为参数,我传递了datacontext,它确实是HardwareComponentViewModel, 但它被冒泡到最外面的ViewModel,其中Binding设置正确(ComputerViewModel)。

<Button cal:Message.Attach="[Event Click] = [Action Expand($dataContext)]">

所以问题是:我需要做些什么才能正确设置Binding? 要在HardwareComponentViewModel中调用ActionMessages,我需要做什么?

3 个答案:

答案 0 :(得分:1)

你试过吗

cal:Action.TargetWithoutContext="{Binding DataContext}"

按钮/网格上的

/您需要的地方?我希望默认情况下操作的目标是当前绑定,但它可能不是(不确定CM如何连接它,可能会查看源)。无论如何,CM需要知道尝试将操作绑定到(VM)的目标是什么,并且由于没有绑定标准CM方式,我的猜测是某些连接无法自动完成,您需要使用上面的代码

答案 1 :(得分:1)

这真的是一个评论,但是我把这个放到答案中,以便进行正确的代码格式化。我在类似的情况下使用过EventTrigger,我记得它完美无缺:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Click">
        <cal:ActionMessage MethodName="Expand" />
    </i:EventTrigger>
</i:Interaction.Triggers>

其中i是System.Windows.Interactivity命名空间,通过

在顶级XAML标记中定义
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

(不确定桌面应用程序的确切行是否应该不同)

你尝试过这样做吗?

答案 2 :(得分:1)

终于成功了!

有效的事件是MouseDown,而不是Click!

<Grid cal:Message.Attach="[Event MouseDown] = [Action Expand($dataContext)]" Background="Lime">

非常感谢你们的帮助!

说实话,我不知道它为什么会起作用,但它会像魅力一样膨胀和坍塌:)