1

几天前我问了这个问题,但答案让我更加困惑。所以我会问一个更简单的问题:

(我正在使用 Caliburn.Micro,这是一个 WPF 应用程序)。假设您有一个 MainView/MainViewModel,它具有子 AView/AViewModel 和 BView/BViewModel。您的 MainView 是一个网格,并且是您要使用 AView 或 BView 填充的单元格之一,具体取决于用户选择。如果我只想显示 AView,我会执行以下操作:

在主视图中:

<StackPanel Name="SP_Controls" VerticalAlignment="Bottom" Grid.Row="1" Grid.Column="0">
    <ContentControl Name="ViewModelToShow" Margin="10" />
</StackPanel> 

在 MainViewModel 中:

public AViewModel ViewModelToShow{get; set;}

我现在天真的想法是做这样的事情:

private AViewModel _AVM;
private BViewModel _BVM;

public ... ViewModelToShow{ get; set;}

然后在代码中,例如,将视图模型设置为显示:

ViewModelToShow = _BVM; 

我唯一的问题是“...”,因为每个 ViewModel 都属于不同的类。有没有办法用泛型来做到这一点,或者我应该为我的 ViewModel 定义一个基类,然后将它们投射到其中?但如果我这样做,它们仍然会正确显示吗?谢谢。

4

3 回答 3

6

您的视图模型应该继承自PropertyChangedBase, 或Screen. Screen继承自PropertyChangedBase,也实现IScreen. Screen添加生命周期(即OnActivate等)。

然后,您可以使用您的方法,即拥有一个名为 eg 的公共属性CurrentViewModel,其类型为IScreen。然后,您可以在需要时将其设置为适当的视图模型。请注意,如果您希望 UI 正确更新,则该CurrentViewModel属性应在引用更改时在 setter 中调用。NotifyOfPropertyChange

或者,您可以将父视图模型视为两个子视图模型的导体,并使用内置的 Caliburn.MicroConductor类型。例如,派生自Conductor<IScreen>.Collection.OneActive.

然后,您可以将 2 个子视图模型添加到父Items集合中,并调用该ActivateItem方法来设置当前视图模型。然后更新您的视图ContentControl以具有x:Nameof ActiveItem

请参阅此处了解更多信息。

于 2012-11-02T21:31:17.533 回答
1

以上所有答案都是正确的。就视图位置的工作方式而言,属性类型无关紧要。只有实例的运行时类型很重要。因此,您甚至可以将属性定义为 object 类型,它仍然可以工作。只需确保您的财产发出变更通知即可。在导体的情况下,ActiveItem 会为您处理。

于 2012-11-03T10:42:52.387 回答
1

我通常从 ViewModelBase 类继承。它是一个包含所有属性更改的类。但由于视图上的 DataContext 属性只是一个对象,因此类型并不重要。

于 2012-11-03T10:49:17.700 回答