【问题标题】:Using caliburn.micro with hierachical viewmodel structure使用具有分层视图模型结构的 caliburn.micro
【发布时间】:2013-05-14 06:16:30
【问题描述】:

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

现在我有一个用于主从视图的大视图模型。

它是分层构建的。

举个例子:

我有一个ComputerView 和一个ComputerViewModel。这里一切正常。

现在这个 ComputerViewModel 包含一个 ObservableCollection<HardwareComponentViewModel>

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

到目前为止,这没问题,因为我可以使用“正常”的绑定方式。 现在我需要在HardwareComponentViewModel 的网格中添加一个ActionMessage

为了更清楚我的意思,这里是完整的 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。 在我试过的网格中: 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)]">

所以问题是:我必须做些什么才能正确设置绑定? 我该怎么做才能调用 HardwareComponentViewModel 中的 ActionMessages?

【问题讨论】:

  • 您可以分享您尝试使用的 XAML 来将 ActionMessage 添加到网格吗?
  • @T045T 请看看我更新的问题
  • @T045T 如果这还不够 XAML,请告诉我。视图真的很大,所以我尽量保持示例简洁。
  • 问题似乎出在网格上。当然,我不能为我的情况设置 caliburn...

标签: c# mvvm binding caliburn.micro


【解决方案1】:

你试过了吗

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

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

【讨论】:

  • 现在已经为网格尝试过这个。如果我单击它,它将不再被正确选择,但不会调用 Action(至少我在 Debug 输出中没有看到它,因为我在插入的按钮中看到它以尝试是否调用了任何操作)。
  • 可能我在这里做错了什么。您能否提供更多关于我必须在这里做什么的信息?
  • 将尝试制作一个小例子来重现该行为。对你来说可能只是一件小事,但现在我不能让它工作
  • @Carleh:请查看我更新的问题,已将 XAML 剥离到最低限度以重现它。
  • @Carleh 终于成功了,请看看我自己的回答。
【解决方案2】:

实际上,这更像是一条评论,但我将其放入答案中以具有正确的代码格式。我在类似的情况下使用过 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"

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

你试过这样做吗?

【讨论】:

  • 在打开 之后插入了这个。似乎没有效果,也许我必须改变一些部分。 (已将 ContactTapped 更改为 Expand,因为这是我要调用的方法的名称)。我必须对“点击”做些什么吗?
  • 抱歉,代码来自移动应用程序 - 我不确定“Tap”是否也适用于桌面,所以我将代码 sn-p 更改为使用“Click” - 另外,由于你的方法没有参数,我把它拿出来了:)
  • 感谢您的更新。现在我一开始得到Action Convention Not Applied: No actionable element for Expand.,但后来我得到Action: Expand availability update.,这让我认为它连接正确。但是如果我点击网格,什么都没有发生,我错过了Invoking Action: Expand. 部分......
  • 您是否为网格设置了背景颜色?如果网格是透明的,它不会捕捉到点击...我认为你可以设置一个完全透明的颜色,它的工作原理类似于透明(但可点击)
  • 是的,我将其设置为“Lime”,但我没有收到任何事件。
【解决方案3】:

终于成功了!

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

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

非常感谢大家的帮助!

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

【讨论】:

  • 可能是因为它在 Grid 上,并且可能 grid 不支持 Click#(或类似性质的东西!) - 很高兴你把它整理好了,正是这些问题占用了很多天在一个项目上:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-28
相关资源
最近更新 更多