Caliburn.Micro如何将View与ViewModel绑定,在ContentControl中显示?

3
我在将视图加载到ContentControl时遇到了一些问题。为了尽可能简单,我使用了带有CM的Hello项目。我确保Hello项目编译正确并能运行。它显示一个带有文本框和按钮的窗口。在运行时,文本框和按钮都与示例ViewModel连接。我修改了ShellView.xaml,用Grid控件替换了StackPanel控件,并设置了4行和1列的网格。我将文本框分配给第一行,将按钮分配给第二行,然后将两个单独的ContentControl分配给最后两行。
<Grid Width="800" Height="600">
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0" Grid.Column="0" x:Name="Name" />
    <Button Grid.Row="1" Grid.Column="0" x:Name="SayHello" Content="Click Me" />
<ContentControl Grid.Row="2" Grid.Column="0" x:Name="TopMenu" 
    VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"></ContentControl>
<ContentControl Grid.Row="3" Grid.Column="0" x:Name="BottomMenu" 
    VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"></ContentControl>
</Grid>

我在ViewModels文件夹中创建了两个不同的C#类,分别为TopMenuViewModel.cs和BottomMenuViewModel.cs,这两个类都继承自PropertyChangedBase类。这只是简单地模仿示例项目中的ShellViewModel.cs类。

using System;
using Caliburn.Micro;
namespace TestWithCaliburnMicro.ViewModels
{
/// <summary>
/// Description of BottomMenuViewModel.
/// </summary>
public class BottomMenuViewModel : PropertyChangedBase
{
    public BottomMenuViewModel()
    {
    }

}

我在Views文件夹中创建了两个单独的WPF用户控件,分别称为TopMenuView.xaml和BottomMenuView.xaml,它们是对应的视图。我在每个xaml中添加了一个标签,其内容为“顶部菜单”或“底部菜单”,以区分这两个控件。

<Grid>
    <Label>Bottom Menu View</Label>
</Grid>

在ShellViewModel.cs类中,我创建了两个公共属性,只设置了“get”访问器以返回相应ViewModel的实例。
    private BottomMenuViewModel _bottomMenu;
    public BottomMenuViewModel BottomMenu {
        get { return _bottomMenu; }
    }

    private TopMenuViewModel _topMenu;
    public TopMenuViewModel TopMenu {
        get { return _topMenu;} 
    }

在任一属性的get访问器中添加断点,可以在调试项目时显示该get访问器被调用。我向BottomMenuViewModel.cs类的构造函数添加了一个简单的语句,例如int x = 0,并在该行添加了一个断点,但是断点从未被触发,这意味着构造函数没有被调用,因此该类实际上没有被创建? 我认为我所做的事情非常基础,并阅读了CM Codeplex网站上的All About Conventions文档,并通过这条评论确认了逻辑:Prior question on stackoverflow 希望有人有时间阅读这篇文章并指点我方向。谢谢。 GitHub上的解决方案。注意:使用SharpDevelop 4.x制作GitHub solution

你能把解决方案放在 Github 上吗?我会下载并仔细查看的。 - Mark W
你在哪里设置 _topMenu_topMenu?因为 Caliburn 不会为你创建 ViewModels。它有两种模式:ViewModel 先,然后它将为 ViewModel 创建一个视图;或者 View 先,当你创建 View 以及 ViewModel 时,Caliburn 只是将它们粘合在一起。 - nemesv
@nemesv:好观点。我遵循的惯例是仅提供get访问器,基于此处的示例HelloScreens项目:链接和HelloScreensWPF项目:链接,它们展示了仅使用get访问器来显示视图。 readonly IDialogManager dialogs; public IDialogManager Dialogs { get { return dialogs; } } - voidmain
你需要在MainViewModel或ShellViewModel(如果你正在使用它)的构造函数中设置ViewModels。 - Mark W
感谢Mark W和nemesv的帮助。通过您有关设置视图的提示以及此答案中的技术,视图现在已加载并已连接到ViewModels:链接在我的情况下,我修改了ShellViewModel的构造函数如下: public ShellViewModel() { this.BottomMenu = new BottomMenuViewModel(); } 建议我还添加了用于加载视图的属性的set访问器。 public BottomMenuViewModel BottomMenu { get { return _bottomMenu; } set { _bottomMenu = value; } } - voidmain
1个回答

0

ShellViewModel的构造函数中实例化您的视图模型,或者如果您希望稍后实例化它们,则将设置器添加到您的视图模型属性,并调用NotifyOfPropertyChange方法来通知 UI 这些属性引用已更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接